当特定状态更改时,我正在try 运行方法.然而,我得到了"达到了最大更新深度".这没有意义,因为该函数将监听从状态A到更新状态B的更改.我try 过做setState(prev => { ...prev, new })个这样的事情.然而,我需要做的不仅仅是将新数据与之前的数据保持一致.

这是我需要运行的函数:

const _updateGraph = (_state: { x: any; y: any; z: any; }) => {
  let X = parseFloat("" + _state.x.toFixed(3));
  let Y = parseFloat("" + _state.y.toFixed(3));
  let Z = parseFloat("" + _state.z.toFixed(3));
  let counter = graphState.counter;
  let stateDataX: { x: number, y: number }[] = graphState.dataX;
  let stateDataY: { x: number, y: number }[] = graphState.dataY;
  let stateDataZ: { x: number, y: number }[] = graphState.dataZ;

  setGraphState({
    dataX: stateDataX.concat({ x: counter, y: X }),
    dataY: stateDataY.concat({ x: counter, y: Y }),
    dataZ: stateDataZ.concat({ x: counter, y: Z }),
    dataObj: { x: X, y: Y, z: Z },
    counter: counter + 1
  });
};

我试图使用的挂钩:

useEffect(() => { 
  _updateGraph({ x, y, z }); 
}, [{ x, y, z }]);

useEffect正在监听{ x, y, z }的更新以更新graphState.这如何导致无限循环?

我唯一能想到的就是重写更新函数,这样我就可以像setState(prev => { ...prev, new })一样使用setState.

推荐答案

React hook的依赖项数组使用浅引用相等判断,并且您在每个渲染周期传递一个新的对象引用,其中{ x, y, z }作为依赖项.这会导致该效果在每个渲染周期中重新运行.

console.log({} === {}); // false
console.log({ x: 1, y: 2, z: 3 } === { x: 1, y: 2, z: 3 }); // false

单独通过xyz作为依赖项:

useEffect(() => { 
  _updateGraph({ x, y, z }); 
}, [x, y, z]);

或者先用useMemo个钩记住对象引用:

const coord3d = React.useMemo(() => ({ x, y, z }), [x, y, z]);

useEffect(() => { 
  _updateGraph(coord3d); 
}, [coord3d]);

此外,任何时候您正在等待状态更新并且下一个状态值取决于当前状态值时,您都应该try 使用功能状态更新.

示例:

const _updateGraph = (_state: { x: any; y: any; z: any; }) => {
  const x = parseFloat("" + _state.x.toFixed(3));
  const y = parseFloat("" + _state.y.toFixed(3));
  const z = parseFloat("" + _state.z.toFixed(3));

  setGraphState(graphState => {
    return {
      dataX: graphState.dataX.concat({ x: counter, y: x }),
      dataY: graphState.dataY.concat({ x: counter, y: y }),
      dataZ: graphState.dataZ.concat({ x: counter, y: z }),
      dataObj: { x, y, z },
      counter: graphState.counter + 1,
    };
  });
};

Typescript相关问答推荐

如何在函数参数中使用(或模仿)`success`的行为?

角形标题大小写所有单词除外

SortKey类型不起作用,尽管它使用的单个类型工作正常<>'

TypeScript Page Routing在单击时不呈现子页面(React Router v6)

如何推断哪个特定密钥与泛型匹配?

使用动态主体初始化变量

参数属性类型定义的REACT-RUTER-DOM中的加载器属性错误

路由链接始终返回到

如何使所有可选字段在打印脚本中都是必填字段,但不能多或少?

如何将别名添加到vitest配置文件?

@TANSTACK/REACT-QUERY中发生Mutations 后的数据刷新问题

为什么我的导航在使用Typescript的React Native中不起作用?

对有效枚举值的常量字符串进行常规判断

为什么受歧视的unions 在一种情况下运作良好,但在另一种非常类似的情况下却不起作用?

TypeScript是否不知道其他函数内部的类型判断?

覆盖高阶组件中的 prop 时的泛型推理

带有 Select 器和映射器的Typescript 泛型

在 next.js 13.4 中为react-email-editor使用forwardRef和next/dynamic的正确方法

为什么我无法在 TypeScript 中重新分配函数?

通过函数将对象文字类型映射到另一种类型的方法或解决方法