useState 钩子 - 传入回调与状态值
useState hook - passing in callback vs state value
在这个非常简单的点击计数器示例中:
const App = () => {
const [count, setCount] = useState(0)
const handleClick = () => {
setCount(count + 1)
}
return <button onClick={handleClick}>{count}</button>
}
我对流量的理解是:
- 组件安装
count
=0
- 单击按钮时,新的
count
状态设置为增量 1。
- 这会触发重新渲染,所以现在我有
count
=1,然后重复。
但是,用同样的理解,为什么这里不行呢?
const App = () => {
const [count, setCount] = useState(0)
useEffect(() => {
const timer = setInterval(() => {
setCount(count + 1)
}, 500)
return () => {
clearInterval(timer)
}
}, [])
console.log(count) // this stops at 1, so the timer stops triggering??
return <h1>{count}</h1> // get stuck at 1
}
上述代码的结果是 count
卡在值 1。(奇怪的是 console.log 也停止了)。
我认为每次触发 setInterval 计时器时,计数增量都会导致重新渲染 new count
值,因此它只会永远增加 1 ?
这里的解决方法是简单地传入一个函数参数来访问 prevState
:
const timer = setInterval(() => {
setCount(oldCount => oldCount + 1)
}, 500)
但为什么第一种方法行不通?
希望有人能给我指出一篇好的文章或文档,我尝试四处搜索但找不到任何解释。
第一种方法行不通,因为这个
setCount(count + 1)
您正在创建回调的那个特定时间的 count 值的副本。这意味着每 500 毫秒你将 re-execute 这一行
setCount(0 + 1)
这不会导致 re-render,因为 React 足够智能,可以理解您将相同的值传递给 setCount 函数,因此 re-render 不是必需的。
然而,通过将回调传递给 setCount:
setCount(oldCount => oldCount + 1)
你是说你想要状态 count 的当前值,所以每次该函数的参数都会不同,因此会导致 re-render.
您可以在此处找到有关此主题的文档:https://reactjs.org/docs/hooks-reference.html#functional-updates
在这个非常简单的点击计数器示例中:
const App = () => {
const [count, setCount] = useState(0)
const handleClick = () => {
setCount(count + 1)
}
return <button onClick={handleClick}>{count}</button>
}
我对流量的理解是:
- 组件安装
count
=0 - 单击按钮时,新的
count
状态设置为增量 1。 - 这会触发重新渲染,所以现在我有
count
=1,然后重复。
但是,用同样的理解,为什么这里不行呢?
const App = () => {
const [count, setCount] = useState(0)
useEffect(() => {
const timer = setInterval(() => {
setCount(count + 1)
}, 500)
return () => {
clearInterval(timer)
}
}, [])
console.log(count) // this stops at 1, so the timer stops triggering??
return <h1>{count}</h1> // get stuck at 1
}
上述代码的结果是 count
卡在值 1。(奇怪的是 console.log 也停止了)。
我认为每次触发 setInterval 计时器时,计数增量都会导致重新渲染 new count
值,因此它只会永远增加 1 ?
这里的解决方法是简单地传入一个函数参数来访问 prevState
:
const timer = setInterval(() => {
setCount(oldCount => oldCount + 1)
}, 500)
但为什么第一种方法行不通? 希望有人能给我指出一篇好的文章或文档,我尝试四处搜索但找不到任何解释。
第一种方法行不通,因为这个
setCount(count + 1)
您正在创建回调的那个特定时间的 count 值的副本。这意味着每 500 毫秒你将 re-execute 这一行
setCount(0 + 1)
这不会导致 re-render,因为 React 足够智能,可以理解您将相同的值传递给 setCount 函数,因此 re-render 不是必需的。
然而,通过将回调传递给 setCount:
setCount(oldCount => oldCount + 1)
你是说你想要状态 count 的当前值,所以每次该函数的参数都会不同,因此会导致 re-render.
您可以在此处找到有关此主题的文档:https://reactjs.org/docs/hooks-reference.html#functional-updates