【问题标题】:Why need to pass dispatch to useEffect?为什么需要将 dispatch 传递给 useEffect?
【发布时间】:2021-06-07 04:42:35
【问题描述】:
 useEffect(() => {
    dispatch(fetchTodo());
  }, [dispatch]);

为什么需要通过dispatch来使用useEffect依赖? 和写不一样

 useEffect(() => {
    dispatch(fetchTodo());
  }, []);

【问题讨论】:

  • 第一个每次dispatch的值变化时执行,第二个在组件挂载时只执行1次
  • 你能比“需要”更具体吗?您是在引用来自 linter 的错误还是省略 dispatch 会导致错误?

标签: reactjs react-redux react-hooks


【解决方案1】:

有时我们需要通过跳过一些效果来优化性能。 在某些情况下,在每次渲染后清理或应用效果可能会产生性能问题。在类组件中,我们可以通过在 componentDidUpdate 中编写与 prevProps 或 prevState 的额外比较来解决这个问题:

componentDidUpdate(prevProps, prevState) {
    if (prevState.count !== this.state.count) {
        document.title = `You clicked ${this.state.count} times`;
    }
}

这个要求很常见,它内置在 useEffect Hook API 中。如果某些值在重新渲染之间没有改变,你可以告诉 React 跳过应用效果。为此,请将数组作为可选的第二个参数传递给 useEffect:

useEffect(() => {
    document.title = `You clicked ${count} times`;
}, [count]); // Only re-run the effect if count changes

在上面的示例中,我们将 [count] 作为第二个参数传递。这是什么意思?如果 count 是 5,然后我们的组件重新渲染 count 仍然等于 5,React 将比较前一次渲染的 [5] 和下一次渲染的 [5]。因为数组中的所有项都是相同的(5 === 5),所以 React 会跳过这个效果。这就是我们的优化。

当我们将计数更新为 6 进行渲染时,React 会将前一次渲染中的 [5] 数组中的项目与下一次渲染中的 [6] 数组中的项目进行比较。这一次,React 将重新应用效果,因为 5 !== 6。如果数组中有多个项目,即使其中一个不同,React 也会重新运行效果。

这也适用于具有清理阶段的效果:

useEffect(() => {
    function handleStatusChange(status) {
        setIsOnline(status.isOnline);
    }

    ChatAPI.subscribeToFriendStatus(props.friend.id, handleStatusChange);
    return () => {
        ChatAPI.unsubscribeFromFriendStatus(props.friend.id, handleStatusChange);
    };
}, [props.friend.id]); // Only re-subscribe if props.friend.id changes

【讨论】:

    【解决方案2】:

    我假设dispatch 的值来自useReducerreact-redux。在useReducer 钩子的第一种情况下,react 保证它将返回相同的函数(每次渲染时的引用相同),因此将其添加到依赖列表不会影响您的调度调用。

    至于react-redux,我认为假设它也返回相同的dispatch 函数是安全的。

    因此,您的 useEffect 挂钩将在何时触发一次,而不是在任何后续渲染中触发。

    请注意,这只是因为每次渲染都返回相同的dispatch。除非用useCallback/useMemo 包装,否则任何任意变量都不会发生同样的情况。

    简而言之,即使您的依赖项列表中的某个值发生更改,useEffect 也会再次触发。由于dispatch 没有改变,它不会再次运行。 React 使用Object.is 来比较值。

    来自反应文档:

    React 保证 setState 函数身份是稳定的,不会 更改重新渲染。这就是为什么从 useEffect 中省略是安全的 或者 useCallback 依赖列表。

    useReducer 返回的调度也是如此。

    如果你知道钩子在幕后是如何工作的,这将更容易理解,如果你有兴趣,我写了一篇博客文章来简化主题。

    https://rohitpotato.hashnode.dev/how-react-implements-usestate-and-useeffect-internally-a-simplified-overview-1

    【讨论】:

      猜你喜欢
      • 2018-05-09
      • 1970-01-01
      • 2016-03-20
      • 2011-03-14
      • 2020-03-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多