React Best Practices
Published: 2022-10-31 16:50:38

## 1. Every prop provided to a component has a default value of true.

When we pass a prop (even without a value), the mere existence of that prop, is going to return true. So if we want to render if true, we can simply write the component like this:

```jsx
export default function App() {
  return (
    <main>
      <Navbar title="My Special App" />
    </main>
  );
}

function Navbar({ title }) {
  return (
    <div>
      {title} // Will not show if false
    </div>
  )
}
```  


## 2. Move Unrelated Code into Separate Components  


Let's say we have this:

```js
export default function App() {
  const posts = [
    {
      id: 1,
      title: "How to Build YouTube with React"
    },
    {
      id: 2,
      title: "How to Write Your First React Hook"
    }
  ];

  return (
    <main>
      <Navbar title="My Special App" />
      <ul> // We could refactor this>>>>>>>>>
        {posts.map(post => ( 
          <li key={post.id}>
            {post.title}
          </li>
        ))}
      </ul> // <<<<<<<<<We could refactor this
    </main>
  );
}

function Navbar({ title }) {
  return (
    <div>
      <h1>{title}</h1>
    </div>
  );
}
```

Is not clean because we can encapsulate that behavior in a separate component and make it easier to read.

The solution, is to create a new component called "_FeaturedPosts_" that is going to render out the posts.

```js
export default function App() {
 return (
    <main>
      <Navbar title="My Special App" />
      <FeaturedPosts />
    </main>
  );
}

function Navbar({ title }) {
  return (
    <div>
      <h1>{title}</h1>
    </div>
  );
}

function FeaturedPosts() {
  const posts = [
    {
      id: 1,
      title: "How to Build YouTube with React"
    },
    {
      id: 2,
      title: "How to Write Your First React Hook"
    }
  ];

  return (
    <ul>
      {posts.map((post) => (
        <li key={post.id}>{post.title}</li>
      ))}
    </ul>
  );
}
```


## 3. Components should live in their own files. Also, if a certain component is only going to live for another component, then it shouldn't have its own file.

```jsx
export function ButtonPrimary({text}){ // We export what we're going to use.
  return(
    <Button class="primary">
      {text}
    </Button>
  )
}

function Button({children}){ // And we don't export what we won't
  return(
    <button>
      {children}
    </button>
  )
}
```


## 4. Inline Styles for less bloated code

This means: Define an object called styles, and then use it into your inline styles. This will be cleaner than passing the entire object to the inline style.

```jsx
export default function App() {
  const styles = {
    main: { textAlign: "center" }
  };

  return (
    <main style={styles.main}>
      <Navbar title="My Special App" />
    </main>
  );
}

function Navbar({ title }) {
  const styles = {
    div: { marginTop: "20px" },
    h1: { fontWeight: "bold" }
  };

  return (
    <div style={styles.div}>
      <h1 style={styles.h1}>{title}</h1>
    </div>
  );
}
```

## 5. If you just need to conditionally render if true, use the Logical AND operator(&&)

This operator checks if the expression on the left is truthy. If the expression is any of those, it will execute/render the part on the right. If not, it will execute the left part.

Note 1: Don't mix with the nullish coalescing operator (??) which checks for undefined or null.

Note 2: Truthy is a set of values that are converted to booleans through _type coercion_.

The example:

```js
import React, { useState } from 'react'

export const ConditionalRenderingWhenTrueBad = () => {
  const [showConditionalText, setShowConditionalText] = useState(false)

  const handleClick = () =>
    setShowConditionalText(showConditionalText => !showConditionalText)

  return (
    <div>
      <button onClick={handleClick}>Toggle the text</button>
      {showConditionalText && <p>The condition must be true!</p>}
    </div>
  )
}
```

## 6. Event handlers can be provided in a different way if only the event is passed.

We usually pass events as (e) => handleSomething(e). But since there is implicit binding here, we can do simply handleSomething() and it will contain the Event context.

```js

import React, { useState } from 'react'

export const UnnecessaryAnonymousFunctionsGood = () => {
  const [inputValue, setInputValue] = useState('')

  const handleChange = e => {
    setInputValue(e.target.value)
  }

  return (
    <>
      <label htmlFor="name">Name: </label>
      <input id="name" value={inputValue} onChange={handleChange} />
    </>
  )
}
```

## 7. When setting the state that depends from the previous state, always access to the previous state and not the state directly.

We need to write it this way, or could lead to unexpected behavior.

```js
import React, { useState } from 'react'

export const PreviousStateGood = () => {
  const [isDisabled, setIsDisabled] = useState(false)

  const toggleButton = () => setIsDisabled(isDisabled => !isDisabled)

  const toggleButton2Times = () => {
    for (let i = 0; i < 2; i++) {
      toggleButton()
    }
  }

  return (
    <div>
      <button disabled={isDisabled}>
        I'm {isDisabled ? 'disabled' : 'enabled'}
      </button>
      <button onClick={toggleButton}>Toggle button state</button>
      <button onClick={toggleButton2Times}>Toggle button state 2 times</button>
    </div>
  )
}
```

Special thanks to @thawkin3 and Freecodecamp Blogs.