# React Components render twice - any way to fix this?

- URL: https://www.heissenberger.at/en/blog/react-components-reder-twice/
- Language: en
- Published: 2020-05-20
- Tags: React JS, Performance

> Tweaking the performance of an App exposes some components using useState render twice.

Many developer have implemented a similar functional component and have seen this behavior. Some have even opened a
[bug report](https://github.com/facebook/react/issues/15074) in the official `React` repository.

> The reason why this happens is an intentional feature of the `React.StrictMode`. It **only happens in development mode**
> and should help to find accidental side effects in the render phase.

Let's find out if there is a way to avoid this problem by trying different implementations.

## A) Functional Component with useState

```javascript
function App() {
  const [click, setClick] = React.useState(0)

  console.log("I render 😡", click)
  return (
    <div>
      <button onClick={() => setClick(click => click + 1)}>Clicks: {click}</button>
    </div>
  )
}
```

if you used `create-react-app` and run your app with `yarn start` you will see the following output in the browser console:

```
I render 😡 0
I render 😡 0
```

if you click the button once, another two lines will be appended to the log:

```
I render 😡 1
I render 😡 1
```

The reason for this is the `React.StrictMode` wrapper in the `index.js` file:

```javascript
ReactDOM.render(
  <React.StrictMode>
    <App />
  </React.StrictMode>,
  document.getElementById("root"),
)
```

> Removing the wrapper `<React.StrictMode>` will solve the problem in development mode. The same is true, if you build the app for
> production with `yarn build && npx serve -p 3001 build`

```
I render 😡 0
I render 😡 1
```

## B) Functional Component with useReduce

I replaced `useState` with `useReduce` and the result was the same:

```javascript
function App() {
  const [clicks, dispatch] = React.useReducer((state, action) => {
    switch (action.type) {
      case "click":
        return state + 1
      default:
        throw new Error()
    }
  }, 0)

  console.log("I render 😡", clicks)
  return (
    <div>
      <button onClick={() => dispatch({ type: "click" })}>Clicks: {clicks}</button>
    </div>
  )
}
```

Browser console:

```
I render 😡 0
I render 😡 0

I render 😡 1
I render 😡 1
```

## C) Class Component

Switching to `Class Comonents` is no difference - you will see the effect even without any state management:

```javascript
class App extends React.Component {
  render() {
    console.log("I render 😡")
    return null
  }
}
```

*Figure: Browser Console Output*

## What is happening behind the scenes?

The main reason is `React.StrictMode` which was introduced in version [16.3.0](https://github.com/facebook/react/releases/tag/v16.3.0).
Back then it only could be used for class components. With the release of [16.8.0](https://github.com/facebook/react/releases/tag/v16.8.0)
it is also applied for hooks.

> StrictMode is a tool for highlighting potential problems in an application. Like Fragment, StrictMode does not render any visible UI.
> It activates additional checks and warnings for its descendants. _‒ official React Documentation_

**`React.StrictMode` currently helps you with:**

- [Identifying components with unsafe lifecycles](https://reactjs.org/docs/strict-mode.html#identifying-unsafe-lifecycles)
- [Warning about legacy string ref API usage](https://reactjs.org/docs/strict-mode.html#warning-about-legacy-string-ref-api-usage)
- [Warning about deprecated findDOMNode usage](https://reactjs.org/docs/strict-mode.html#warning-about-deprecated-finddomnode-usage)
- [Detecting unexpected side effects](https://reactjs.org/docs/strict-mode.html#detecting-unexpected-side-effects)
- [Detecting legacy context API](https://reactjs.org/docs/strict-mode.html#detecting-legacy-context-api)

In most cases it will throw an error message into the browser console log. It **fails to automatically detect render side effects**
as they often can be non-deterministic behavior.

To detect side effects the following functions are invoked twice:

- Class component constructor, render, and shouldComponentUpdate methods
- Class component static getDerivedStateFromProps method
- Function component bodies
- State updater functions
- Functions passed to useState, useMemo, or useReducer (any Hook)

## Why should I use React.StrictMode?

React will soon provide a new **[Concurrent Mode](https://reactjs.org/docs/concurrent-mode-intro.html)** which will break render work
into multiple parts. Pausing and resuming the work between this parts should avoid the blocking of the browsers main thread.

> This means that the render phase could be invoked multiple times and should be a [Pure Function](https://en.wikipedia.org/wiki/Pure_function) without any side effects!

If you did not used `React.StrictMode` because you started in the early React days or have been annoyed by the double rendering of your components
I hope that I was able to convince you to use it now to aviod any surprise when switching to concurrent mode in the near future.

[Write a response on Medium](https://medium.com/p/91cf23961625/responses/show)
