console.log printing twice in React? That is React StrictMode in action
Published: 2022-12-27 18:18:47

---
title: console.log printing twice in React? That is React StrictMode in action
published: true
date: 2022-12-13 00:00:00 UTC
tags: 
canonical_url: https://www.frontendundefined.com/posts/react-issues/double-console-react-18/
---

Despite all the tools we have for debugging frontend code, nothing beats a quick console.log to check the current state of the app. For years, I have temporarily stuffed console.log statements in all nooks and crannies within components and I was surprised when I did the same in a [fresh CRA app](https://create-react-app.dev/docs/getting-started) recently and found it printed twice in the console.

```javascript
const App = () => {
   console.log('render');
   return (
     <div className="App"> 
       ...
     </div>
   )
}
```

![Screenshot of the chrome dev tools console showing console.log being printed twice](https://www.frontendundefined.com/posts/react-issues/double-console-react-18/react-double-console-log-718w.jpeg "Why is this printing twice?")

Historically, this meant that the component was being re-rendered. But in this case, I couldn't figure out why the component was re-rendering since the state was not changing. After some digging, I found out that this "double console.log" was due to [React StrictMode](https://reactjs.org/docs/strict-mode.html).

## Quick intro to React StrictMode

Over the last few years, React has been moving towards [Interruptible rendering](https://17.reactjs.org/docs/concurrent-mode-intro.html#interruptible-rendering) which allows the rendering to be paused or changed after it has begun and [Concurrency](https://17.reactjs.org/docs/concurrent-mode-intro.html#concurrency) to handle multiple state updates at the same time. In order to enable these features, React components must be idempotent meaning that they must return the same output all the time given then same input. Historically, React components were not encouraged to be idempotent with lifecycle functions like componentWillMount and componentWillReceiveProps encouraging us to write logic that should only run sometimes (Usually on the first render). So any components with this "unsafe" behavior must be refactored to be idempotent in order for them to be used in newer versions of React with concurrency enabled.

With React 18, the concurrent features were enabled with the new [createRoot entrypoint](https://reactjs.org/blog/2022/03/08/react-18-upgrade-guide.html#updates-to-client-rendering-apis) and CRA changed its template to use the createRoot entrypoint and use [React StrictMode](https://reactjs.org/docs/strict-mode.html).

```javascript
...
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
    <React.StrictMode>
       <App />
    </React.StrictMode>
);
```

StrictMode is designed to show issues with components that will make them unusable with concurrent React. When enabled, it prints warnings about the usage of deprecated React features and modifies the behavior of React in development mode so that any issues with components become more visible. One such behavior change is that several functions and methods (e.g. Class component constructor + render, function component bodies) are [invoked twice](https://reactjs.org/docs/strict-mode.html#detecting-unexpected-side-effects) This explains why the console.log statement was printing twice!

## How to get console.log to print only once again?

The easy fix is to disable React StrictMode by removing the component wrapper. But this would leave us blind to potential issues in the components we create.

The proper fix is to install the [React developer tools browser extension](https://reactjs.org/blog/2015/09/02/new-react-developer-tools.html) which marks the double invoked console.log in a lighter color.

![Screenshot of the chrome dev tools console showing console.log with React developer tools](https://www.frontendundefined.com/posts/react-issues/double-console-react-18/react-double-console-log-dev-tools-718w.jpeg "console.log with React developer tools installed")