代码链接:https://codesandbox.io/s/charming-colden-3browz?file=/src/App.js
我刚刚开始使用Redux,我在src/store/sizeSlice.js
中定义了一个切片,我的redux存储在src/store/store.js
中。现在的想法是,当两个按钮(addCol
,addRow
)被单击时,它们将调度操作来增加行数和列数的全局状态。我在App.js
中使用了两个useSelector
钩子。
现在只要我点击其中一个按钮,就会有四个输出到控制台,比如我点击addRow
,就会有一个控制台日志selectRow
,三个控制台日志selectCol
,我知道函数组件调用useSelector
,在本例中为App.js
重新呈现。应该只有两个输出(一个selectRow
,和一个selectCol
),但是为什么选择器函数被调用了三次呢?特别是与它相关的按钮(本例中为dispatch addCol
操作)未被单击?
1条答案
按热度按时间rqmkfv5c1#
React有时会在“渲染阶段”,多次“渲染”应用,,以计算在“提交阶段”***期间应渲染(即刷新)到DOM***的差异。“提交阶段”通常被视为React组件的“渲染”阶段,因为这是我们看到UI更新的时候。
为什么这种区分很重要?
注意,* 整个 * React函数组件主体是“呈现”方法,并且“呈现”方法在“可由React暂停、中止或重新启动”的“呈现阶段”期间被调用。这意味着React可根据需要多次调用“呈现”方法,以便在协调过程期间(即,当状态更新已被排队并被处理时)计算差异。
您在
useSelector
钩子回调中将控制台日志记录为 * 无意的副作用 。这些日志不应该与组件重新渲染或被渲染到DOM多次混淆。这些日志是“渲染阶段”的意外副作用,可能会发生多次。
如果你想记录状态更新作为状态更新-〉渲染到DOM*的结果,那么把所有的控制台日志移到一个
useEffect
钩子中。useEffect
钩子用于运行 * 故意 * 副作用。1 React组件渲染== 1故意副作用。应用示例: