Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
380 views
in Technique[技术] by (71.8m points)

reactjs - How to run useEffect and setState multipletime on useEffect

I am trying to re-arrange a state two times, however, the state only takes in effect on the last useState, what can I use to re-arrange a state multiple time?

Code as below:

import React, { useState, useEffect } from "react";
import ReactDOM from "react-dom";

import "./styles.css";

function App() {

  const [array, setArray] = useState([6,2,5,4,1]);

  // async update from useEffect
  useEffect(() => {
    updateArray(array,2,1)
    updateArray(array,4,2)
  }, []);

  const updateArray = (localArray, to, from) => {
    let tempArray = [...localArray];
    tempArray.splice(to, 0, tempArray.splice(from, 1)[0]);
    setArray(tempArray);
  };
 

  console.log("render", array);
  return (
    <div className="App">
      <h1>Hello CodeSandbox</h1>
      <h2>Start editing to see some magic happen!</h2>
    </div>
  );
}

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);

I know a way is by using setTimeOut and update one by one, however, if my state gets re-render late, it will eventually glitch. Is there any alternative?

I am expecting the array to be [6, 5, 4, 1, 2] because first change to [6, 5, 2, 4, 1] and seconds change to [6,5,4,1,2]

However, it only runs the last one which becomes [6, 2, 4, 1, 5]

Expected Output

First setState: [6, 5, 4, 1, 2]
Second setState: [6, 5, 2, 4, 1]

Current Output

Second setState: [6, 2, 4, 1, 5]

Can I also know the reason for this happening?

CodeSandBox link

question from:https://stackoverflow.com/questions/65842042/how-to-run-useeffect-and-setstate-multipletime-on-useeffect

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

Issue

When enqueueing more than 1 state update within a render cycle you should use a functional state update to update from the previous state, not the state from the previous render cycle. When the latter happens each enqueued update overwrites the previous update so the last update wins.

Solution

Use a functional state update.

useEffect(() => {
  updateArray(2, 1);
  updateArray(4, 2);
}, []);

const updateArray = (to, from) => {
  setArray(prevState => {
    const tempArray = [...prevState];
    tempArray.splice(to, 0, tempArray.splice(from, 1)[0]);
    return tempArray
  });
};

Edit how-to-run-useeffect-and-setstate-multipletime-on-useeffect


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...