# React 17: Design Patterns and Best Practices - Notes

I recently read React 17: Design Patterns and Best Practices. I was able to add a lot to my React toolset. Here are ALL my takeaways (will likely have a condensed version for the most important takeaways in the future).

\*\*Note - most of the text in this document is taken directly from the book. These are notes/quotes, not my own content.

# React Overview

### Declarative vs Imperative

React enforces a declarative programming paradigm.

Imperative describes how things work and all the instructions are included. Like giving instructions to a bartender:

1. Find a glass and collect it from the shelf
    
2. Place the glass under the tap
    
3. Pull down the handle until the glass is full
    
4. Hand me the glass
    

While declarative is just describing the outcome - "Can I have a beer, please?"

```plaintext
// Imperative approach
const toUpperCase = input => {
    const output = []
    for (let i = 0; i < input.length; i++) {
        output.push(input[i].toUpperCase());
    }
    return output;
}

// Declarative approach
const toUpperCase = input => input.map(value => value.toUpperCase())
```

In declarative programming, developers only describe what they want to achieve, and there's no need to list all the steps to make it work. React handles the rest.

### TypeScript Types

Types help us to describe our objects or arrays in a better way.

```plaintext
type TUser = {
    username: string
    name: string
    age: number
    email: string
}
```

It is good practice to preface your types with `T` (`TUser`)

### TypeScript Interfaces

Interfaces are very similar to types, and sometimes developers don't know the differences between them. Syntax is a little different from types

```plaintext
inteface IUser {
    username: string
    name: string
    age: number
    email: string
}
```

It is good practice to preface interfaces with `I` (`IUser`)

An interface can be defined multiple times and will be treated as a single interface (all declarations will be merged)

```plaintext
interface IUser {
    username: string
    name: string
}
interface IUser {
    country: string
}
const user: IUser = {
    username: 'chad'
    name: 'michael murray'
    country: 'croatia'
}
```

You can also extend `interfaces` and `types`, but the syntax is different:

```plaintext
interface IWork {
    company: string
    position: string
}
interface IPerson extends IWork {
    name: string
    age: number
}

type TWork = {
    company: string
    position: string
}
type TPerson = TWork & {
    name: string
    age: number
}
```

# Styling/Formatting

### Align closing tag with opening tag

```plaintext
<button
    foo="bar"
    veryLongPropertyName="baz"
    onSomething={this.handleSomthing}
/>
```

### Ternaries make the code more compact

```plaintext
<div>
    {isLoggedIn ? <LogoutButton /> : <LoginButton />
</div>
```

### Using helper functions for conditions

Avoid polluting our code with conditionals so that it is easier to understand and reason about

```plaintext
const canShowSecretData = () => {
    return dataIsReady && (isAdmin || userHasPermissions);
}
return (
    <div>
        {canShowSecretData() && <SecretData />}
    </div>
)
```

### Plugin for conditionals: `jsx-control-statements`

Not entirely sure how I feel about this solution, but it is interesting nonetheless.

`npm install --save jsx-control-statements`

(had some issues actually implementing this... deprecated?)

```plaintext
// Gets compiled into a ternary expression
<If condition={this.canShowSecretData}>
    <SecretData />
</If>

// Gets compiled into multiple ternary expressions
<Choose>
    <When condition={...}>
        <span> if </span>
    </When>
    <When condition={...}>
        <span> else if </span>
    </When>
    <Otherwise>
        <span> else </span>
    </Otherwise>
</Choose>
```

### Prettier will format your code

Avoid doing this in code reviews

### Inline Styles

In general, we should avoid inline styles. They make it difficult to debug, as the CSS is no longer in classes, and directly into the markup. With lots of elements doing this, it quickly gets out of hand and is difficult to find.

It is impossible to use pseudo-selectors (`:hover` ) with inline styles.

However, they do offer some unique benefits for special circumstances. The main one is that we can calculate and recalculate CSS values on the client at runtime.

```plaintext
height of div is dependent upon state and values at runtime
const style {
    height: someStateValue * 10
}

<div style={style}>
    ...
</div>
```

### Radium Library

Radium is a library that allows you to use inline styles with pseudo-classes using Radium HOC's

```plaintext
import Radium from 'radium'
const Button = () => <button>Click Me!</button>
export defualt Radium(Button)
```

### Atomic CSS Modules

using micro-classes to build the styles of components

```plaintext
.mb0 {
    margin-bottom: 0;
}
.fw6 {
    font-weight: 600;
}

// Apply to markup
<h2 class="mb0 fw6">Hello React</h2>
```

Similar to Tailwind CSS. I am not a big fan of this.

### Styled Components

Use the `styled` function to create any element by using `styled.elementName`, where `elementName` can be a `div`, a `button`, or any other valid DOM element.

Then define the style of the element by using an ES6 feature called **tagged template literals.**

```plaintext
const Button = styled.button`
    backgroundColor: #FFFFFF;
    width: 320px;
    padding: 20px;
    borderRadius: 5px;
    &:hover {
        color: #fff;
    }
    &:active {
        position: relative;
        top: 2px;
    }
`
```

This also allows for pseudo-classes, but when it is compiled, it creates a unique class name and adds it to the element, then injects the corresponding style in the head of the document.

```plaintext
// as if it were like so
<button class="kYvFOg">Click Me!</button>

// styles
.kYvFOg {
    backgroundColor: 'red';
    ...
}
```

I don't fully understand this, but it is powerful.

# Programming Concepts

### Functional Programming

Data is considered immutable and side effects are avoided

### High-Order Functions

Functions that take a function as a parameter, and optionally some other parameters, and return a function. The returned function is usually enhanced with some special behaviors.

```plaintext
const add = (x, y) => x + y

const log = fn = (...args) => {
    return fn(...args)
}
const LogAdd = log(add)
```

### Purity

A function is pure when there are no side effects, which means that the function does not change anything that is not local to the function itself.

### Currying

The process of converting a function that takes multiple arguments into a function one argument at a time and returning another function.

```plaintext
// Say we have the following code
const add = (x, y) => x + y

// We can instead define the function as follows
const add = x => y => x + y

// We use it the following way
const add1 = add(1)
add1(2)    // 3
add1(3)    // 4
```

### Composition

Small, simple, testable pure functions that can be composed together

```plaintext
const add = (x, y) => x + y
const square = x => x * x

const addAndSquare = (x, y) => square(add(x, y))
```

# Hooks

### FC Type

Used to define a Functional Component in React. Can pass in props like this

```plaintext
type Props = {
    propX: string
    propY: string
    propX: string
}
const Issues: FC<Props> = ({ propX, propY, propX }) => {...}
```

### UseEffect

Handles all the previous life cycle events - `componentDidMount`, `componentDidUpdate`, `componentWillUnmount` - depending on the syntax of `useEffect()`

```plaintext
// Equivalent of componentDidMount() method
// runs upon rendering/mounting component
useEffect(() => {
    // Perform side effect here
}, []);

// This is kind of a combination of componentDidMount, componentDidUpdate,
// and componentWillUnmount
useEffect(() => {
    // This code will run when any of the dependencies in the array
    // change or are updated
}, [depA, depB]);
```

### Using functions inside `useEffect`

Every time you want to use a function inside the `useEffect` Hook, you need to wrap your function with the `useCallback` Hook

```plaintext
const fetchIssues = useCallback(async () => {
    const response = await axios(url)
    if (response) setIssues(response.data)
}, [url]);

useEffect(() => {
    fetchIssues()    // is wrapped with useCallback
}, []);
```

### `useRef`

There might be cases where you need to access the underlying DOM nodes to perform some imperative operations. This should be avoided if possible.

### `Children` Prop

There is a special prop that can be passed from the owners to the components defined inside their render - `children.`

It is described as **opaque** because it is a property that does not tell you anything about the value it contains. Components can also be defined with nested components inside them, and they can access those children using the `children` prop.

Consider the following scenario:

```plaintext
// Button that has a TEXT property for the display text
const Button = ({ text }) => (
    <button className="btn">{text}</button>
)

// Can then be used in the following way
<Button text="click me!" />

// Which would then be rendered as:
<button class="btn">click me!</button>
```

But what if we want to display more than just a string in this button? Icons, images, labels, etc.

We could add multiple parameters to `Button` and include logic to handle each of the specialized cases.

Or, we can use the `children` prop and make `Button` just a wrapper.

```plaintext
const Button = ({ children }) => (
    <button className="btn">{children}</button>
)
```

In this case, any element we wrap inside the `Button` component will be rendered as a child of the `button` element with `btn` as the class name.

```plaintext
<Button>
    <img src"..." alt="..." />
    <span>Click me!</span>
</Button>

// would then be rendered as 
<button class="btn">
    <img src"..." alt="..." />
    <span>Click me!</span>
</button>
```

### Container and Presentational Patterns

React components typically contain a mix of *logic* and *presentation*. This pattern helps us to separate these concerns. This can help the component become more reusable.

One file for the presentation (anything inside the render method), one file for the logic (helpers, API calls, data transformations, etc.).

### HOC's (High-Order Components)

### React Context API

Provides a way to share data between components without passing a prop to all the child components.

To consume the context (use the Context API), we need to wrap the component with a Provider.

```plaintext
const App = () => {
    return (
        <IssueProvider url="...someURL">
            <Issues />     // this is where we want to consume api
        </IssueProvider>
    )
}
```

IssueProvider might look something like this

```plaintext
const IssueProvider: FC<Props> = ({ children, url }) => {
    // State
    const [issues, setIssues] = useState<Issue[]>([])
    
    const fetchIssues = useCallback(async () => {
        const response = await axios(url)
        if (response) setIssues(response.data)
    }, [url]);

    useEffect(() => {
        fetchIssues()
    }, []);

    const context = {
        issues,
        url
    }

    return <IssueContext.Provider value={context}>{children}</IssueContext.Provider>
}
export default IssueProvider
```

And you might consume the Context API like this

```plaintext
import { FC, useContext } from 'react'
import { IssueContext, Issue } from './contexts/Issue'

const Issues: FC = () => {
    // Here you consume Context, grab the issues val
    const { issues, url } = useContext(IssueContext)

    return (
        <>
            issues.map((issue: Issue) => (
                ... // do something with issues from Context
            )
        </>
    )
}
```

### Generic Event Handlers

We might run into scenarios where a component has multiple event handlers, and a lot of boilerplate code comes along with them. In these situations, we can implement a single, generic event handler like so:

```plaintext
const handleEvent = (event) => {
    switch (event.type) {
        case: 'click':
            console.log('clicked');
            break
        case: 'dblclick':
            console.log('double clicked');
            break
        defualt:
            console.log('unhandled', event.type)
    }
}

// Attach event listener to onClick and onDoubleClick attributes
return (
    <button
        onClick={handleEvent}
        onDoubleClick={handleEvent}
    >
        Click Me!
    </button>
)
```

### Reconciliation

The React Library implements different techniques to `render` our components fast and to touch the Document Object Model (DOM) as little as possible. Applying changes to the DOM is usually expensive, so minimizing the number of operations is crucial.

When React has to display a component, it calls its `render` method and the `render` methods of it children recursively. The `render` method of a component returns a tree of React elements, which React uses to decide which DOM operations have to be done to update the UI.

Whenever the component state changes, React calls the `render` method on the nodes again, and it compares the result with the previous tree of React elements. The library is smart enough to figure out the *minimum set of operations required to apply the expected changes on the screen*. This process is called **reconciliation**, and it is managed transparently by React.

### Keys and Reconciliation

```plaintext
// Lets say we have a list of two items
<ul>
    <li>Carlos</li>
    <li>Javier</li>
</ul>

// Now lets add an item at the end of the list
<ul>
    <li>Carlos</li>
    <li>Javier</li>
    <li>Emmanuel</li>
</ul>
```

When we add an element to the end of this list, and React needs to re-render, it looks at the two trees and notices that the two trees are the same, so it will keep the two trees and insert the `<li>Emmanuel</li>` tree.

But when we add the item to the beginning of the list...

```plaintext
<ul>
    <li>Emmanuel</li>
    <li>Carlos</li>
    <li>Javier</li>
</ul>
```

React looks at the two trees and notices that they are not the same, so it re-renders the entire tree. Instead of realizing it can keep the subtrees of `<li>Carlos</li>` and `<li>Javier</li>` intact. This is quite a difference in optimization.

This is solved with the `key` attribute.

```plaintext
<ul>
    <li key="2018">Carlos</li>
    <li key="2019">Javier</li>
</ul>

<ul>
    <li key="2017">Emmanuel</li>
    <li key="2018">Carlos</li>
    <li key="2019">Javier</li>
</ul>
```

React knows that the `2017` key is the new one, and that the `2018` and `2019` keys have just moved.

Finding a key is not hard. The element that you will be displaying might already have a unique ID. So the key can just come from your data.

`<li key={element.id}>{element.title}</li>`

The key has to only be unique among its siblings. An item index in the array can be passed as a key, but it is considered bad practice. However, if the items are never reordered, this can work well. The reorders will seriously affect performance.

### Immutability

The new React hooks, such as `React.memo`, use a shallow comparison method against the props, which means that if we pass an object as a prop and we mutate one of its values, we do not get the expected behavior.

In fact, a shallow comparison cannot find mutation on the properties and the components never get re-rendered, except when the object itself changes.

```plaintext
const [state, setState] = useState({})
const obj = state.obj;
obj.foo = 'bar';
setState({ obj })
```

The above code will not set the state as expected. Even if the value of `foo` is changed, the reference to the object is still the same and the shallow comparison does not recognize it.

Instead, we need to create a new instance every time we mutate the object.

```plaintext
const obj = Object.assign({}, state.obj, { foo: 'bar' })
setState({ obj })
```

And with ES6 and Babel, we can use the **object spread operator:**

```plaintext
const obj = { ...state.obj, foo: 'bar' }
setState({ obj })
```

`immutable.js` is a popular library with some immutability helpers that make it easy to work with immutable objects.

### React DevTools

Installing React DevTools for Chrome allows you to inspect the rendered tree of components and check which properties they have received and what their state is at a particular point in time.

Props and states can be read, and they can be changed in real time to trigger updates in the UI and see the results straight away.

There is a new feature that can be enabled by ticking the **Trace React Updates** checkbox. When this functionality is enabled, we can use our application and visually see which components get updated when we perform a particular action. The updated components are highlighted with colored rectangles, and it becomes easy to sport possible optimizations

### React Router

There is plenty in the book about React Router, but I will only include a small takeaway, something that was new and important to me.

Using the `<Link>` component:

``<Link to={`/contacts/${contact.id}`}>{contact.name}</Link>``

The &lt;Link&gt; component will generate an `<a>` tag that points to `/contacts/contact.id`

Then we will have something like the following in the `AppRoutes` Component:

`Route path="/contacts/:contactId" component={Contacts} exact/>`

```plaintext
const AppRoutes = () => {
    <App>
        <Switch>
            <Route path="..." ... />
            <Route path="..." ... />
            <Route path="/contacts/:contactId" component={Contacts} exact/>
        </Switch>
    </App>
}
```

React Router has a special prop called `match`, which is an object that contains all the data related to the route, and if we parameters, we will be able to see them in the `match` object:

```plaintext
const Contacts: FC<Props> = (props) => {
    const { match: { params: { contactId } } } = props;
    // can now use contactId as var
}
```

The `match` prop looks like this:

```plaintext
match: {
    isExact: true
    params: { contactId: "2" }
    path: "/contacts/:contactId"
    url: "/contacts/2"
    __proto__: Object
    staticContext: undefined
}
```

### Server Side Rendering (SSR)

SSR should only be enabled when strictly necessary. For example, if you need SEO (Search Engine Optimization) or if you need to customize the social sharing information, you should start thinking about it.

# AntiPatterns to be avoided

### Initializing the state using properties

Ex: `const [count, setCount] = useState<number>(props.count);`

This has two main issues:

1 - We have a duplicated source of truth

This makes it unclear which is the current and trustworthy value to use inside the component and to display to the user. The values can diverge...

```plaintext
<Counter>
Props:
    count: 1
State:
    count: 2
```

2 - If the `count` property passed to the component changes, the state does not get updated

If the value of the property changes during the life cycle of the application (let's say it becomes 10), the `Counter` component will never use the new value, because it has already been initialized.

### Using Indexes as a Key

This has already been discussed in the **Reconciliation** section.

Simply put, using the wrong key can give us unexpected behaviors in some instances, and can affect performance.

The key has to be unique and stable

# Contributing to React

### Share your React code

Sharing your code forces you to follow best practices and write better code. It also exposed your code to feedback and comments from other developers. This is a big opportunity for you to receive tips and improve your code to make it better.

Another significant opportunity that open source can give you is letting you get in touch with smart and passionate developers from all around the world. Working closely with new people who have different backgrounds and skill sets is one of the best ways to keep our minds open and improve ourselves.

### Publishing an npm package

The most popular way of making a package available to developers is by publishing it to `npm`, the package manager for Node.js.

**Semantic Versioning:**

`v 0.1.0`

The last number of the package on the right represents the patch. The middle number indicates the minor version of the release and it should be changed when new features are added to the library. The first number on the left represents the major version, and it has to be increased when a version containing breaking changes is released to the public.

# Glossary

**JWT** - JSON Web Token

**Imperative Programming** - Describing how things work

**Declarative Programming** - Describing what you want to achieve. Being declarative means that you just describe what you want to be displayed on the screen at any point in time and React takes care of the communications with the browser.

**Uncontrolled Component** - like regular HTML form inputs for which you will not be able to manage the value yourself but instead, the DOM will take care of handling the value and you can get this value by using a React ref.

**Controlled Component** - a React component that controls the values of input elements in a form by using the component state. Full control over the values in the fields
