You're mixing up two different problems here. console.log(people) is an empty array because you've already called useState, and it's already returned an empty array, because the state was an empty array at the beginning of that render. So even though setPeople updates the state, your people variable doesn't magically update: it's already captured the value it had at the beginning of that render. So you need to wait for the next render to see the updated value. In other words, you can't log state immediately after updating it, and expect to see the updated value. Instead, you could move your console.log(people) to be immediately before the return ... so you're seeing what the state is before the render. Now, you say you get an error in " person.name " - you haven't explained what the error is, so we can't help you with this error. Chances are the /people endpoint isn't returning what you think it's returning. Answer from Deleted User on reddit.com
🌐
GitHub
github.com › facebook › react › issues › 25593
Bug: setState inside useEffect is unreliable in React 18 · Issue #25593 · facebook/react
October 31, 2022 - Otherwise any guards put in useEffect may not work as expected, especially as new code are added, called functions are changed, etc..., which makes React works in an unreliable way. I created a demo project in CodeSandbox that shows the issue (Maximum update depth exceeded):
Author   lucasbasquerotto
🌐
Reddit
reddit.com › r/reactjs › use effect why my setstate is not updating state?
r/reactjs on Reddit: Use Effect why my setState is not updating state?
July 14, 2021 -
import React, { useEffect, useState } from 'react';
import './App.css';
import api from './api/peope';
import { async } from 'q';
import peope from './api/peope';
function App() {

  const [people,setPeople] = useState([]);

  const retreivePeople = async () => {
    const response = await api.get("/people");
    return response.data;
    
  }

  useEffect(() => {

    const getAllPeople = async () => {
      const allPeople = await retreivePeople();
      if(allPeople)
       setPeople(allPeople)
       console.log(people)
       
 
    };

    getAllPeople();



  },[]);

  return (
    <div>

      {people.map(person => {
        return (
          <div>
            <h1>{person.name}</h1>
          </div>
        )
      })}

      </div>
  );
}

export default App;

I get an error since in person.name since when I console.log(people) I get an empty array people is not being updated by setPeople

Discussions

Can I set state inside a useEffect hook
If I pass useEffectValue in the output array, I get an infinite loop. ¯_(ツ)_/¯ 2021-08-03T15:05:54.677Z+00:00 ... Effects are always executed after the render phase is completed even if you setState inside the one effect, another effect will read the updated state and take action on it ... More on stackoverflow.com
🌐 stackoverflow.com
State variable not updating in useEffect callback?
Do you want to request a feature or report a bug? Bug, maybe? Although thinking about it more makes me think I've misunderstood something. What is the current behavior? scroll state variable up... More on github.com
🌐 github.com
27
November 1, 2018
reactjs - setState not updating state after useEffect - Stack Overflow
I'm making a shopping cart app and I have a variable that loops through all prices and gets a total price of the cart. I am trying to have that total amount update the totals state through setTotal... More on stackoverflow.com
🌐 stackoverflow.com
setstate doesn't seem to work inside useeffect
getCards is asynchronous so you need to await it. All functions defined as asynchronous return a promise. You will have to alter how you’re doing it as you can’t call await directly in a use effect because you can’t declare the callback as async. Please note I’m just reading your code so I could be wrong. As mentioned you also can’t console log updated state until it rerenders More on reddit.com
🌐 r/reactjs
11
0
January 16, 2022
🌐
DEV Community
dev.to › catur › best-implement-setstate-on-useeffect-3je9
Best Implement setState on useEffect - DEV Community
October 21, 2022 - This warning appears because we are advised to add a state to the second argument array of useEffect, in this way, useEffect will not re-render its callback function unless there is a change in the state. let's fix our previous code: This way ...
Top answer
1 of 6
245

Generally speaking, using setState inside useEffect will create an infinite loop that most likely you don't want to cause. There are a couple of exceptions to that rule which I will get into later.

useEffect is called after each render and when setState is used inside of it, it will cause the component to re-render which will call useEffect and so on and so on.

One of the popular cases that using useState inside of useEffect will not cause an infinite loop is when you pass an empty array as a second argument to useEffect like useEffect(() => {....}, []) which means that the effect function should be called once: after the first mount/render only. This is used widely when you're doing data fetching in a component and you want to save the request data in the component's state.

2 of 6
189

For future purposes, this may help too:

It's ok to use setState in useEffect . To do so, however, you need to ensure you don't unintentionally create an infinite loop.

An infinite loop is not the only problem that may occur. See below:

Imagine that you have a component Comp that receives props from parent and according to a props change, you want to set Comp's state. For some reason, you need to change for each prop in a different useEffect:

DO NOT DO THIS

useEffect(() => {
  setState({ ...state, a: props.a });
}, [props.a]);

useEffect(() => {
  setState({ ...state, b: props.b });
}, [props.b]);

It may never change the state of a , as you can see in this example: https://codesandbox.io/s/confident-lederberg-dtx7w

The reason this occurs is that both useEffect hooks run during the same react render cycle. When props.a and props.b change at the same time, each useEffect captures the same stale state value from before the update. As a result, when the first effect runs, it calls setState({ ...state, a: props.a }) . Then, the second effect runs immediately after and calls setState({ ...state, b: props.b}) with the same stale state value, thereby overwriting the first update. The result is that a never appears to update. The second setState replaces the first one rather than merging the two updates together.

DO THIS INSTEAD

The solution to this problem is to call setState like this:

useEffect(() => {
  setState(previousState => ({ ...previousState, a: props.a }));
}, [props.a]);

useEffect(() => {
  setState(previousState => ({ ...previousState, b: props.b }));
}, [props.b]);

For more information, check the solution here: https://codesandbox.io/s/mutable-surf-nynlx

With this approach, you will always receive the most updated and correct value of the state.

🌐
GitHub
github.com › facebook › react › issues › 14066
State variable not updating in useEffect callback? · Issue #14066 · facebook/react
November 1, 2018 - What is the current behavior? scroll state variable updates in rendered output but not inside handleScroll event callback. I reckon this might be due to the fact that when handleScroll is defined scroll is 0, but scroll is defined in the scope above and should be updated when the component is re-rendered. import React, { useState, useEffect } from "react"; const Scroller = () => { const [scroll, setScroll] = useState(window.scrollY); const handleScroll = () => { console.log(scroll); // scroll is always 0 setScroll(window.scrollY); }; useEffect(() => { window.addEventListener("scroll", handleScroll); return () => window.removeEventListener("scroll", handleScroll); }, []); // runs once return <div id="scroll">{scroll}</div>; // scroll is correct }; export default Scroller;
Author   evolutionxbox
Top answer
1 of 2
4

I think your approach of a card code is not the good one.

Here you always have the same information twice: you're getting the total in total and then you're setting totals with that same result. You can simplify by keeping only one of the two variables.

Also your code here is not working because the useEffect will never be executed: As you have put totals as a dependency, but it never changes. Even if you change totals somwhere else, you will have an infinite loop because in the useEffect depending on totals's changes, it change it value, which will execute the useEffect that changes totals etc etc, infinite loop.

I think your loop should also be in a useEffect with no dependencies as it will be executed only at the first render.

I would do soemthing like that, and maybe the code can be move improved:

  const [prices, setPrices] = useState([1, 3, 6, 39, 5]);
  const [total, setTotal] = useState(0);

  useEffect(() => {
    // Sets total with already present products in the card
    // This useEffect is called only at the first render
    prices.forEach((price) => {
      setTotal((total) => total + price);
    });
  }, []);

  useEffect(() => {
    setTotal((total) => total + prices[prices.length - 1]);
     // Called when prices values changes, like if you're adding a product to your card
     // It keeps your total updated
  }, [prices]);

  const addPrice = () => {
    // Simulate a new product in your card
    setPrices((prices) => [...prices, Math.floor(Math.random() * 10)]);
  };

  return (
    <div className="App">
      <p>total: {total}</p>
      <button onClick={() => addPrice()}>add price</button>
    </div>
  );

I hope I'm clear in my answer lol

2 of 2
0
  const [finalTotal, setFinalTotal] = useState(0);

  let total = 0;
  for (let i = 0; i < prices.length; i++) {
    total += prices[i];
  }

  useEffect(() => {
    setFinalTotal(total);
  }, [total, setFinalTotal]);

https://codesandbox.io/s/stackoverflowhelp-i70fd?file=/src/App.js

🌐
LogRocket
blog.logrocket.com › home › why react doesn’t update state immediately
Why React doesn't update state immediately - LogRocket Blog
November 26, 2024 - As we saw above, state updates are inherently asynchronous processes. When you call the setState function, React schedules an update rather than immediately applying the changes. When you invoke setState, React maintains a queue of pending updates.
🌐
Linguine Code
linguinecode.com › home › blog › why react setstate/usestate does not update immediately
Why React setState/useState does not update immediately
December 19, 2020 - React setState and useState are asynchronous actions. React setState and useState only create queues for React core to update the state of React components.
Find elsewhere
🌐
Reddit
reddit.com › r/reactjs › setstate doesn't seem to work inside useeffect
r/reactjs on Reddit: setstate doesn't seem to work inside useeffect
January 16, 2022 -

I made a very simple (for learning purposes) cards app and I defined a context. Inside context file:

const [flashcards, setFlashcards] = useState([])

useEffect( () => {
console.log("flashcards in effect -- 1",flashcards)
getCards();
console.log("flashcards in effect -- 2",flashcards)
}, [])

const getCards = async () => {
const resp = await axios.get("/api/flashcards")
console.log("RESPONSE: ", resp)
const alldata = resp.data
console.log("DATA read in getcards: ", alldata)
try {setFlashcards(alldata)}
catch(err){console.log("ERROR in setting flashcards:: ", err)}
console.log("---flashcards set to: ", flashcards)
}
Now when the app loads this context, I can see in the console:

flashcards in effect 1: empty array //OK

flashcards in effect 2: empty array

// Wait. This should be seen after the console.logs in getCards are printed

RESPONSE: // An object

DATA read in getcards: // An array of nine so reading data was successful

---flashcards set to // an empty array

So it seems that setFlashcards doesn't work when called from function getCards inside useEffect. How can I make it work?

🌐
Frontend Undefined
frontendundefined.com › posts › react-issues › react-usestate-hook-not-updating-immediately
Is your React useState hook not updating state immediately? Here's how to fix it
January 4, 2023 - // What setState really does under the hood // (Not really, but a simplified example) const setCount = (newCount) => { React.stateUpdates.push('count', newCount); } const increment = () => { setCount(count + 1); // Only asks React to re-render the component with this new value. alert('The count is ' + count); // count will retain the old value until the next render. } You can calculate the updated value within the function and use it.
🌐
freeCodeCamp
forum.freecodecamp.org › javascript
React useState not updating the variable - JavaScript
April 14, 2023 - Problem There is no syntax errors. Function parseLocalStorage returns a object White using setStorage(parseLocalStorage()) at useState Storage does’nt get modified setStorage used in other functions (like { const [hasParsed , setH...
Top answer
1 of 2
3

Setting the state in React acts like an async function.
Meaning that the when you set the state and put a console.log right after it, it will likely run before the state has actually finished updating.

Which is why we have useEffect, a built-in React hook that activates a callback when one of it's dependencies have changed.

In your case you're already using useEffect to update the state, but if you want to act upon that state change, or simply to log it's value, then you can use another separate useEffect for that purpose.

Example:

useEffect(() => {
   console.log(isActive)
   // Whatever else we want to do after the state has been updated.
}, [isActive])

This console.log will run only after the state has finished changing and a render has occurred.

  • Note: "isActive" in the example is interchangeable with whatever other state piece you're dealing with.

Check the documentation for more info about this.


Additional comments:

  • Best to avoid using the loose != to check for equality/inequality and opt for strict inequality check instead, i.e. - !==
    Loose inequality is seldom used, if ever, and could be a source for potential bugs.

  • Perhaps it would better to avoid typing this as boolean | undefined.
    Unless justified, this sounds like another potential source for bugs.
    I would suggest relying on just boolean instead.

2 of 2
2

First, you can't get the state's updated value immediately after setting it because State Updates May Be Asynchronous

useEffect(() => {
        if (params_user_id?.id != null) {
            const SINGLE_USER_URL = `users/${params_user_id.id}/edit`;
            const getSingleUser = async () => {
                const {data} = await axios.get(SINGLE_USER_URL)
                console.log(data)
                setIsActive(data.isactive)
                console.log('isactive', isActive) // <-- You can't get updated value immediately
            }
            getSingleUser();
        }
}, [params_user_id])

Change the type of useState to boolean only and set the default value to false.

const [isActive, setIsActive] = useState<boolean>(false);

Then, in Form.Check, update onChange to this:

 <Form.Check
      defaultChecked={isActive}
      className='mb-3'
      type='checkbox'
      id='active'
      onChange={() => setIsActive((preVal) => !preVal)}
      label='Active: Unselect for deleting accounts.'
  /> 
🌐
Reddit
reddit.com › r/reactjs › confusion about 'bad practice' of setting state in useeffect - looking for some clarification
r/reactjs on Reddit: Confusion about 'bad practice' of setting state in useEffect - looking for some clarification
December 27, 2024 -

I'm curious about this general guideline and trying to get an understanding of whats considered bad, and what might be considered 'just fine'

From what I can tell, is if your useEffect is constrained by something in the dependency array, then you can set state just fine. Am I wrong? A rough example:

const [fooBarState, setFooBarState] = useState(false);
const { setOtherStateHook } = useOtherStateHook();

useEffect(() => {
  if (!fooBarState) { // assuming some logic elsewhere that changes this
      setOtherStateHook(<data>); // internally calls useState
  }
}, [fooBarState]);

In the above example, we don't have to worry about some inifinite re-rendering loop, right? Is this an okay usage of setting state (by way of custom hook) in useEffect?

🌐
BOSC Tech Labs
bosctechlabs.com › home › blog › how to solve changes not reflecting when usestate set method applied?
Steps to Solve Changes Not Reflecting When useState Set Method Applied
August 1, 2024 - ... Using a Temp Variable: In case the “useState” method is not reflecting the immediate change, any temporary variable can be used. The use of a temporary variable with “await” may ask the API to take time and then set the value.
🌐
freeCodeCamp
forum.freecodecamp.org › javascript
React functional component setState not updating the state
August 30, 2020 - I am building a Pomodoro clock as described in Free Code Camp curriculum here. Code is available here. In Timer component, isSessionMode state which holds a boolean value is toggled conditionally in startTimer method (line: 40) as below. setIsSessionMode((prev) => !prev); But the state doesn’t seem to be updated because the logger in useEffect hook doesn’t print the state (line: 19) after setIsSessionMode() is called as below. useEffect(() => { console.log(isSessionMode) ...
🌐
GitHub
github.com › facebook › react › issues › 14369
setState hook inside useEffect can cause unavoidable warning Can't perform a React state update · Issue #14369 · facebook/react
December 1, 2018 - To fix, cancel all subscriptions and asynchronous tasks in a useEffect cleanup function. in Child (created by Holder) SET VISIBLE AFTER · In our case we have this even without RAF call, but on transitionend DOM event.
Author   istarkov
🌐
GitConnected
levelup.gitconnected.com › react-hooks-gotchas-setstate-in-async-effects-d2fd84b02305
React hooks gotchas: setState in async useEffect | by Thomas Juster | Level Up Coding
April 7, 2022 - The problem is: in fetchedUser().then(), we triggered two setStates, and instead of having one render as expected, we have one render per setState call. Important note:This happens only with async actions (aka promises in useEffect).
🌐
Medium
medium.com › @kunaltandon.kt › useeffect-setstate-the-infinite-loop-4fa0b6dba637
useEffect & setState — The infinite loop! | by Kunal Tandon | Medium
September 6, 2023 - Here’s what happens: changing the state triggers useEffect, which then triggers setState. And guess what? This merry-go-round keeps going, causing an infinite loop of updates.