首页 > 解决方案 > 如何在 useEffect 上多次运行 useEffect 和 setState

问题描述

我正在尝试重新排列一个状态两次,但是,该状态只对最后一个 useState 生效,我可以使用什么来多次重新排列一个状态?

代码如下:

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);

我知道一种方法是使用 setTimeOut 并逐个更新,但是,如果我的状态重新渲染较晚,它最终会出现故障。有没有其他选择?

我期望数组为 [6, 5, 4, 1, 2] 因为首先更改为 [6, 5, 2, 4, 1] 秒更改为 [6,5,4,1,2]

但是,它只运行最后一个变成 [6, 2, 4, 1, 5]

预期产出

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

电流输出

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

我也可以知道发生这种情况的原因吗?

CodeSandBox链接

标签: reactjs

解决方案


问题

在渲染周期内将超过 1 个状态更新入队时,您应该使用功能状态更新来更新前一个状态,而不是前一个渲染周期的状态。当后者发生时,每个排队的更新都会覆盖先前的更新,因此最后的更新获胜。

解决方案

使用功能状态更新。

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
  });
};

编辑 how-to-run-useeffect-and-setstate-multipletime-on-useeffect


推荐阅读