Double-Invoke of State Functions in React
Tags: react
Published: 2020-03-27 19:53:13

---
title: Double-Invoke of State Functions in React
published: true
description: Explanation for the seemingly quirky behavior of why you'll see state functions be executed twice in your React application.
cover_image: https://dev-to-uploads.s3.amazonaws.com/i/dz1s1pvnr9qzt4e4gu6o.jpg
tags: react
---

# Overview
This article covers the seemingly unexpected behavior of seeing multiple executions of a component's state functions (`setState()` for class-based components and `useState()` for functional components that use React hooks).

# Intro - Seeing Double Logs
The project started out like any other. Spin up a `create-react-app` project, find an API to play with ([Open Weather API](https://home.openweathermap.org/) in this case), create call to said API when the component loads, add a few console logs to verify the data is coming in how I want and...

Hold up... am I seeing double?

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/miwp61za9lc63y56bptc.png)

At this point, I had put a console.log after initializing my state variable and after updating it with the weather information from the API. However, I was unexpectedly seeing 2 logs for each of those steps!

# Simplifying and Further Debugging

Googling resulted in articles about how to architect your React app, Hook tutorials, and the like. Although interesting, they were not the answer. So instead, I set up another `create-react-app` to debug this behavior further and replaced `App.js` with the following:

```javascript
import React, {useState} from 'react';

function App() {
    const [obj] = useState({ var1: 1, var2: 2 });

    console.log(obj);

    return <h1>See dev console.</h1>;
  }

export default App;
```

Again, I was able to see the logged state variable was getting duplicated, **immediately**, with no API call involved.

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/ywn0qqza9u0gblbz7go8.png)

Was I already building a poorly architected React application? Admittedly, I'm still getting my feet wet with Hooks, but have I already messed up something in only 3 lines of code??? **Cue imposter syndrome.**

After making some queries to the #react-help channel of the [Scrimba](https://scrimba.com/) discord server, an answer was found:

THIS BEHAVIOR IS PER DESIGN.

Yes indeed! The reason for the double-firing of the state function was due to React's **Strict Mode** being enabled. Looking back at our project, you can see the `index.js` file controls how this is enabled.

```javascript
ReactDOM.render(
  <React.StrictMode> // <--------------- BAM
    <App />
  </React.StrictMode>,
  document.getElementById('root')
);
```

The [React Docs](https://reactjs.org/docs/strict-mode.html#detecting-unexpected-side-effects) actually covers this behavior in the _Detecting Unexpected Side Effects_ section. It's also important to note that this **only happens in Development mode**.

> "This only applies to development mode. Lifecycles will not be double-invoked in production mode."

On a Github issue, Dan Abramov himself had this to say:

> "It is expected that setState updaters will run twice in strict mode in development. This helps ensure the code doesn't rely on them running a single time (which wouldn't be the case if an async render was aborted and alter restarted). If your setState updaters are pure functions (as they should be) then this shouldn't affect the logic of your application." - Dan Abramov ([source](https://github.com/facebook/react/issues/12856#issuecomment-390206425))

# Further Observations
It should be mentioned that this double-invoke doesn't happen all the time depending on what types of state variables you have set up and how many. For example, `String`, `Number`, and `Boolean` would not cause a double-invoke by themselves. However, `Object` and `Array` types would.

**All code snippets below are the content of the `App()` function which always returns `<h1>See dev console.</h1>`.**

## Number, String, and Boolean
```javascript
const [numericVal] = useState(1)
console.log(numericVal)

// 1
```
```javascript
const [stringVal] = useState("stringVal")
console.log(stringVal)

// stringVal
```
```javascript
const [booleanVal] = useState(true)
console.log(booleanVal)

// true
```

## Object and Array
```javascript
const [obj] = useState({var1: 1,var2:2});
console.log(obj)

// Object { var1: 1, var2: 2 }
// Object { var1: 1, var2: 2 }
```
```javascript
const [arr] = useState([1,2,3,4])
console.log(arr)

// Array(4) [1, 2, 3, 4]
// Array(4) [1, 2, 3, 4]
```

Now most of the time, you won't just have a single `useState()` variable in a component. Trying with multiple actually results in the double-invoke behavior once again no matter the type of variable you declare. Here's a few examples:

```javascript
const [stringVal] = useState("stringVal")
const [booleanVal] = useState(true)

console.log(stringVal)
console.log(booleanVal)

// stringVal
// true
// stringVal
// true
```
```javascript
const [numericVal] = useState(1)
const [stringVal] = useState("stringVal")
const [booleanVal] = useState(true)

console.log(numericVal)
console.log(stringVal)
console.log(booleanVal)

// 1
// stringVal
// true
// 1
// stringVal
// true
```
```javascript
const [numericVal] = useState(1)
const [arr] = useState([1,2,3,4])

console.log(numericVal)
console.log(arr)

// 1
// Array(4) [1, 2, 3, 4]
// 1
// Array(4) [1, 2, 3, 4]
```

(If anyone has any insight as to what exactly triggers a double-invoke, please comment and I'll be sure to update this article!)

# Conclusion
If you're ever concerned that you're logging more than you anticipated or double-invoking certain functions in your local development environment, be sure to check if you're running in React's Strict Mode!

# Resources
* [React.StrictMode causes setState to fire twice](https://github.com/facebook/react/issues/12856)
* [Strict Mode - React Docs](https://reactjs.org/docs/strict-mode.html)