Reactjs 为什么需要通过调度来发挥作用?

Reactjs 为什么需要通过调度来发挥作用?,reactjs,react-redux,react-hooks,Reactjs,React Redux,React Hooks,为什么需要传递dispatch以使用效果依赖关系? 这与写作不同 useEffect(() => { dispatch(fetchTodo()); }, [dispatch]); 有时我们需要通过跳过一些效果来优化性能。 在某些情况下,每次渲染后清理或应用效果可能会产生性能问题。在类组件中,我们可以通过在componentDidUpdate中编写与prevProps或prevState的额外比较来解决此问题: useEffect(() => { dispat

为什么需要传递
dispatch
以使用效果依赖关系? 这与写作不同

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

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

 useEffect(() => {
    dispatch(fetchTodo());
  }, []);
这个需求非常常见,它被内置到useEffect钩子API中。如果在重新渲染之间某些值没有更改,则可以告诉React to skip应用效果。为此,请将数组作为可选的第二个参数传递给useEffect:

componentDidUpdate(prevProps, prevState) {
    if (prevState.count !== this.state.count) {
        document.title = `You clicked ${this.state.count} times`;
    }
}
在上面的示例中,我们将[count]作为第二个参数传递。这是什么意思?如果计数为5,然后我们的组件在计数仍然等于5的情况下重新渲染,React将比较上一次渲染的[5]和下一次渲染的[5]。因为数组中的所有项都相同(5==5),React将跳过效果。这就是我们的优化

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

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

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

我认为您应该再次阅读该文档,以清楚地理解useEffect的概念

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

至于
react redux
,我认为可以安全地假设它也返回相同的
dispatch
函数

因此,您的
useffect
钩子将在任何后续渲染时触发一次

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

简而言之,任何时候,即使依赖项列表中的某个值发生更改,
useffect
也会再次触发。由于
dispatch
没有更改,因此不会再次运行。React使用
Object.is
来比较值

从react文档:

React保证setState函数标识是稳定的,不会 重新渲染时的更改。这就是为什么从useffect中省略是安全的 或使用回调依赖项列表

useReducer
返回的分派也是如此

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


第一个将在每次分派值更改时执行,第二个仅在组件上执行一次。您能比“需要”更具体吗?您引用的是来自linter的错误,还是忽略
dispatch
会导致错误?
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