使用依赖多个道具的useEffect跟踪一个道具

时间:2020-02-12 12:00:22

标签: javascript reactjs typescript react-hooks

有一个看起来像这样的代码:

const MyComponent: React.FC<MyComponentProps> = ({
    trackMyChanges,
    iChangeEverySecond
}) => 
{
    // React Hook useEffect has missing dependencies: 'iChangeEverySecond'
    useEffect(() => {
        calculateData(trackMyChanges, iChangeEverySecond);
    }, [trackMyChanges]);   
    
    return <> ... </>;
}

calculateData道具被更改的情况下,代码执行trackMyChanges。一切正常,但我收到警告,提示iChangeEverySecond依赖项丢失。我不想运行该钩子,因为iChangeEverySecond已更改。处理这种情况的正确方法是什么?

3 个答案:

答案 0 :(得分:3)

您可以使用useCallback挂钩解决此问题:

const calculateData = useCallback(() => {
  console.log(iChangeEverySecond);
}, [iChangeEverySecond]);

useEffect(() => {
  calculateData(trackMyChanges);
}, [trackMyChanges, calculateData]);

因此,每次iChangeEverySecond更改时,它将重新定义您的calculateData函数为它的最新版本,但是只有在trackMyChanges更改时才会触发它。

答案 1 :(得分:0)

这是由于范围。您已经了解到,数组是一个元素,可以帮助useEffect更新匿名函数中使用的道具或状态。在您的情况下,iChangeEverySecond是props,因此它“应该”,不一定要在数组中,因为它是在函数内部使用的。

我给你一个完整的解释,摘自React网站。

如果使用此优化,请确保数组包含所有值 从组件范围(例如道具和状态)转变过来 时间和效果所使用的时间。否则,您的代码将 参考先前渲染中的陈旧值。进一步了解如何 处理函数以及数组值也更改时的操作 经常。

如果您要运行效果并仅将其清理一次(在挂载和 卸载),则可以传递一个空数组([])作为第二个参数。这个 告诉React你的效果不依赖于道具的任何值 或状态,因此它不需要重新运行。这不是特殊处理 情况—直接取决于依赖项数组始终如何 有效。

如果传递一个空数组([]),则效果中的道具和状态 将始终具有其初始值。同时通过[]作为第二个 参数更接近熟悉的componentDidMount和 componentWillUnmount心智模型,通常有更好的解决方案 避免过于频繁地重新运行效果。另外,别忘了React 将useEffect推迟到浏览器绘制完毕后再进行,这样 多余的工作没什么问题。

我们建议将穷举下降规则用作我们的一部分 eslint-plugin-react-hooks软件包。当依赖项是 指定不正确并提出修复建议。

答案 2 :(得分:-1)

这是因为 iChangeEverySecond 每次在 trackMyChanges 上运行。改变了。要处理此场景,您可以在首次加载时在本地存储中添加 ichangeEverySecond ,然后在每次 trackMyChanges 更改时在useEffect中获取它。

localStorage.setItem(“ iChangeEverySecond”,iChangeEverySecond)

useEffect(()=> {

    calculateData(trackMyChanges, localStorage.getItem(iChangeEverySecond));
}, [trackMyChanges]);