调用外部函数时,旧的“ useEffect缺少依赖项”

时间:2020-07-04 15:39:30

标签: reactjs use-effect

是的,我知道这个问题已经问过无数次了,但是没有一个答案适合我的代码。

我的useEffect()调用一个外部函数(showIncrement()),该函数记录我的increment状态值。问题是showIncrement()也被按钮使用,所以我不能在useEffect()范围内移动它。

我知道一些解决方案:

  • useEffect()中重新创建函数,但是然后我有两个相同的函数
  • 使用React useCallback()函数,React文档将其称为不得已,而其他问题中的其他答案也不建议使用它,所以我不太确定< / li>

问题是,什么是解决此问题的最佳方法?使用useCallback()安全吗?

这是我的代码:

const App = () => {
    const [increment, setIncrement] = React.useState(2);
    const showIncrement = React.useCallback(() => console.log(increment), [
        increment,
    ]);

    React.useEffect(() => {
        showIncrement();
    }, [showIncrement]);

    return (
        <div className="App">
            <button type="button" onClick={showIncrement}>
                Show Increment
            </button>
        </div>
    );
};

2 个答案:

答案 0 :(得分:0)

如果showIncrement不需要访问来更新状态变量,则解决此问题的最简单方法是将其移动到组件之外,因此不会在每个渲染器上都重新创建它并具有稳定的引用:

const showIncrement = (increment) => console.log(increment);

const App = () => {
    const [increment, setIncrement] = React.useState(2);

    React.useEffect(() => {
        showIncrement(increment);
    }, [increment]);

    return (
        <div className="App">
            <button type="button" onClick={() => showIncrement(increment)}>
                Show Increment
            </button>
        </div>
    );
};

另一种方法是使用useCallback钩子:

const App = () => {
  const [increment, setIncrement] = React.useState(2);
  const showIncrement = React.useCallback(() => console.log(increment), [
    increment
  ]);

  React.useEffect(() => {
    showIncrement();
  }, [showIncrement]);

  return (
    <div className="App">
      <button type="button" onClick={showIncrement}>
        Show Increment
      </button>
    </div>
  );
};

答案 1 :(得分:0)

据我所知,您想:

  • 重新使用showIncrement逻辑。
  • 在组件的安装架上运行showIncrement
  • 不违反棉绒警告。

这里的问题是showIncrement取决于状态值increment,所以无论哪种方式,您的useEffect都必须在dep数组中包含increment

通常,useCallback的dep数组(在这种情况下为[increment]不经常更改

因此,根据您的用例,由于showIncrement仅触发onClick,所以这似乎是一个不错的选择。

const App = () => {
  const [increment] = React.useState(2);
  const isMounted = useRef(false);

  const showIncrement = useCallback(() => {
    console.log(increment);
  }, [increment]);

  React.useEffect(() => {
    if (!isMounted.current) {
      showIncrement();
    }
  }, [showIncrement]);

  return (
    <div className="App">
      <button type="button" onClick={showIncrement}>
        Show Increment
      </button>
    </div>
  );
};