javascript - React:useReducer Hook 首先触发两次,不是 StrictMode
问题描述
这不是StrictMode引起的问题。
这是我的代码,一个计数器:
let outsideCount = 0
function Counter() {
const [count, setCount] = useReducer(doCounting, 0)
function doCounting(count) {
console.log(`count: ${count}`)
console.log(`outsideCount: ${outsideCount}`)
console.log('---------divider---------')
outsideCount++
return count + 1
}
return (
<div>
<span>count: {count}</span>
<button onClick={setCount}>Click Me!</button>
</div>
)
}
和输出:单击1次:
count: 0
outsideCount: 0
---------divider---------
count: 0
outsideCount: 1
---------divider--------- // <<<<<<< That's the point I confused. why it triggered twice?
点击2次:
count: 1
outsideCount: 3 // <<<<<<< I KNEW that cause by StrictMode
---------divider--------- // this time it only trigger once.
// ^^^^^^^^^ but why it trigger twice only at the first click?
点击3次:
click 3 time:
count: 2
outsideCount: 5 // <<<<<<< I KNEW that cause by StrictMode
---------divider---------
// ^^^^^^^^^ the third time trigger once like expected. the first-click confused me.
我已经知道StrictMode每次点击都会outsideCount
添加两次,因为它测试了一些程序员可能不会注意到的副作用。
在构建为生产之后,outsideCount
按预期添加一次。
但是为什么第一次点击会触发doCounting
两次功能呢?我第console
一次点击时显示 2 个分隔线。
此外,在构建为生产之后,当我第一次单击时doCounting
仍然触发两次。
不寻找其他解决方案或好的/坏的做法,只是想知道为什么
解决方案
尽管行为或代码的运行顺序尚不清楚,
但我想我对此有所了解:function-memory-address
该功能doCounting
被触发并在第一次单击时执行某些操作:
--->console
打印,value
返回,
然后重新渲染组件,因此再次doCounting
重新创建该功能。
然后,不知何故,再次触发重新创建的函数
我想第二次是 React 真正想做的正确方式。我猜。
避免函数内存地址更改的最简单方法就像我们避免对象内存地址更改的相同方法:useMemo
或useCallback
或declare-it-outside
// useMemo
const doCounting = useMemo(() => value => {
console.log(value)
console.log('---divider---')
return value + 1
}, [])
//or
// useCallback
const doCounting = useCallback(value => {
console.log(value)
console.log('---divider---')
return value + 1
}, [])
尽管我仍然不知道函数何时被触发,但至少我们知道这是内存地址问题。
希望有人补充正确代码的运行顺序。谢谢
推荐阅读
- c# - 实现读取器/写入器 - 航空公司预订示例
- linux - 用于显示特定日期的进程的 shell 脚本
- python - Pandas 将单元格 tex 拆分为列
- python - 如何将项目放入子列表中?
- c++ - STM32F1 写/读闪存,Cortex M3
- elasticsearch - 在 Kibana /ElasticSearch 中搜索多个字段
- javascript - 如何在本地存储中设置 AWS Cognito 令牌
- python - 返回另一个函数的函数 '->' 符号
- python - 如何在不复制任何第一个输出的情况下打印第二个输出?
- python - 用于返回频繁项集的 SQL 查询,如 Python 示例