Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

355
Visualizações
Why useState hook don't update while using loop inside useEffect()

Case 1:

    const [present, setPresent] = useState([]);
     
    useEffect(() => {
    
        for (var j = 1; j <= totalPeriod; j++) {
          setPresent([
            ...present,
            {
              period: j,
              present: true,
            },
          ]);
        }
    
    }, []);

Case 2:


    const [present, setPresent] = useState([]);
    
    let createPresent = [];
    for (var j = 1; j <= totalPeriod; j++) {
      createPresent = [
        ...createPresent,
        {
          period: j,
          present: true,
        },
      ]
    }
    
    useEffect(() => {
      setPresent(createPresent);
    }, []);

When I am trying to update the present state using loop in inside useEffect() in Case 1, present state is not updating. But when I am separately using loop outside the useEffect() and creating an array which I am then assigning to present state in case 2, the present state is getting updated.

What is the reason behind this? Why present state is not updating in Case 1?

over 4 years ago · Santiago Trujillo
3 Respostas
Responde à pergunta

0

In the below case, your present state is not the result of each subsequent state update but rather the initial one which you had which is []. React will batch these updates and not make them happen synchronously so effectively there will be just one state update with present updated to latest entry in your for loop.

  const [present, setPresent] = useState([]);
     
    useEffect(() => {
    
        for (var j = 1; j <= totalPeriod; j++) {
          setPresent([
            ...present,
            {
              period: j,
              present: true,
            },
          ]);
        }
    
    }, []);

In the below case, you are first assembling a createPresent array with all the values you need and finally calling the state updator function i.e. setPresent to set the state.

const [present, setPresent] = useState([]);
    
    let createPresent = [];
    for (var j = 1; j <= totalPeriod; j++) {
      createPresent = [
        ...createPresent,
        {
          period: j,
          present: true,
        },
      ]
    }
    
    useEffect(() => {
      setPresent(createPresent);
    }, []);

In order to achieve the second behaviour with first, you can make use of the state updator callback which holds the previous state as the argument like so :-

  const [present, setPresent] = useState([]);
     
    useEffect(() => {
    
        for (let j = 1; j <= totalPeriod; j++) {
          setPresent(prevState=>[
            ...prevState,
            {
              period: j,
              present: true,
            },
          ]);
        }
    
    }, []);

Here also state update is batched but previous state is factored in before updating the next one.

When I say a batched state update, I mean there will only be a single render. You can verify that by doing console.log('render') in your component's function body.

Note the use of let instead of var here since let is scoped you will get the accurate value for the variable j.

over 4 years ago · Santiago Trujillo Relatório

0

The assumption you're making in Case 1 is that the setPresent call is synchronous and that it updates present immediately, while in reality state updates in React are almost always asynchronous. Thus the present variable inside for (var j = 1; j <= totalPeriod; j++) { will be equal to the original value, which is an empty array []. So in essence, you're setting the state to this over and over:

  [
      ...[],
     {
        period: j,
        present: true,
     },
  ]

This will result in your state being updated to the last array the for loop creates. So if totalPeriod is equal to 5, your state will end up being [{period: 5, present: true}] instead of [{period: 1, present: true}, {period: 2, present: true}, ... ]

In Case 2, everything is very straightforward, you assemble the array without messing with state variables and then set the state in one shot. Just like you're supposed to in this case.

over 4 years ago · Santiago Trujillo Relatório

0

In addition to other answers:

You need to keep some key points in your mind while updating states in React component. First of all updating state in React state is not synchronous, hence will be batched unless you trigger it asynchronously.

state = { count: 0};
increment() {
    this.setState({ count: this.state.count + 1});
    this.setState({ count: this.state.count + 1});
    this.setState({ count: this.state.count + 1});
    console.log(this.state.count) // 0
}

increment() 
console.log(this.state.count); // 1

And, the final value of this.state.count will be 1 after completion of the calling incemenent()

Because React batch the all calls up, and figure out the result and then efficiently make that change. Kind of this pure JavaScript code, merging where last one wins

newState = Object.assign(
    {},
    firstSetStateCall,
    secondSetStateCall,
    thirdSetStateCall,
);

So, we can say here everything has to do with JavaScript object merging. So there's another cool way, where we pass a function in setState instead of object.

Secondly, in case of react hooks useState, the updating function(second element of the array returned by useState()) doesn't rerender on the content's change of the state object, the reference of the state object has to be changed. For example: here I created sandbox: link

had I not changed the reference of the array (which is the state), it would not rerender the components.

 for (let key in newState) {
      newStateToBeSent[key] = newState[key]; // chnaging the reference
    }
over 4 years ago · Santiago Trujillo Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda