繁体   English   中英

React, useEffect 仅当依赖数组的 2 个元素被更新时

[英]React, useEffect only when 2 elements of dependency array are updated

我有一个 React 表组件,其中Column组件和按钮组件都呈现在列内,触发一些 function。 表格示例:

    <Table>
      <Column onCellClick={handleCell}>
        <button onClick={handleButton} />
      </Column>
    </Table>

这两个句柄函数在同一次单击时被调用,它们会触发一些useStates

    const [cell, setCell] = useState(false);
    const [buttonValue, setButtonValue] = useState(false);

    const handleCell = (value) => setCell(value)
    const handleButton = (value) => setButtonValue(value)

所以我有一个useEffect必须仅在cellbuttonValue都更新时触发某些代码。 目前我有类似的东西:

    useEffect(() => {
      if (cell && buttonValue) {
        // some code
        setAnotherState(etc)
      }
    }, [cell, buttonValue]);

我的问题是,如果我非常快速地单击或在随机场景中单击,则在实际更新setAnotherStatecell之前调用buttonValue if在 useEffect 中,它只会在我第一次实际更新这两个值时才能正常工作,因为它们都被初始化为false ,但是,通过多次点击,会有一些过时的设置状态。

有什么提示吗? 在执行if中的代码之前,如何确保两个状态都实际更新?

我无法删除这 2 个 onClick 或 onCellClick 中的任何一个,它们的组件都有不同的特定值,所以我都需要它们。

这是一个使用useRef将集合 state 存储为 integer 值的想法,您可以对其进行测试。

Cell 将 state 加 2(首先取 2 的模数以删除现有的 2 个值),Button 加 1(首先进行位移和 x2 以消除第一位)。 当 stateRef 为 3 时,效果知道两者都已更改,设置另一个 state,并将 stateRef 重置为 0。

    const [cell, setCell] = useState(false);
    const [buttonValue, setButtonValue] = useState(false);
    const stateRef = useRef(0);

    const handleCell = (value) => {
      setCell(value);
      stateRef.current = stateRef.current % 2 + 2;
    };
    const handleButton = (value) => {
      setButtonValue(value);
      stateRef.current = (stateRef.current >> 1) * 2 + 1;
    };

然后

    useEffect(() => {
      if (stateRef.current == 3) {
        // some code
        setAnotherState(etc)
        stateRef.current = 0;
      }
    }, [stateRef.current]);

你可以这样做:

const [cell, setCell] = useState(null);
// it stores the updated status for cell
const [cellStatus, setCellStatus] = useState(false);
const [buttonValue, setButtonValue] = useState(null);
// it stores the updated status for buttonValue
const [buttonValueStatus, setButtonValueStatus] = useState(false);

const handleCell = (value) => {
  setCell(value)
  setCellStatus(true) // it carried a updated event
}
const handleButton = (value) => {
  setButtonValue(value)
  setButtonValueStatus(true)  // it carried a updated event
}

useEffect(() => {
  // !!(null) === false
  if (!!cellStatus && !!buttonValueStatus) {
    // some code
    setAnotherState(etc)
    // here you reset their status since they were already updated and used
    // now they are not new values but old ones
    setCellStatus(false) 
    setButtonValueStatus(false)
  }
}, [cell, buttonValue]);

因此,基本思想是跟踪一个变量中的值和另一个变量中的更新状态。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM