React state 更新原理(三) - state 快照的总结和实践
state 变量可能看起来像您可以读取和写入的常规 JavaScript 变量。但是,state 的行为更像是快照。设置它不会更改您已有的 state 变量,而是会触发重新渲染。
这个系列的文章你将学习到:
如何设置 state 的触发器进行重新 render
state 何时以及如何更新
设置 state 后为什么状态不会立即更新
事件处理程序如何访问 state 的“快照”
系列文章
React state 更新原理 - render 时使用 state 的快照
React state 更新原理(二) - state 随时间的变化
总结
设置 state 会进行新的 render。
React 将 state 存储在组件之外,就像在架子上一样。
当您调用
useState
时,React 会为您提供这次 render 中 state 的快照。变量和事件处理程序在 re-render 时不会“幸存”。每次 render 都有自己的事件处理程序。
每次 render(以及其中的函数)将始终“看到”React 赋予该 render 的 state 快照。
你可以在心里替换事件处理程序中的 state,类似于你对 render 出的 JSX 的看法。
过去创建的事件处理程序具有创建它们的时候 render 的 state 值。
实践 - 交通灯切换
学习完了这个系列的三篇文章,我们通过一个例子来加深印象吧~
这是一个人行横道灯组件,当按钮被按下时会切换:
import { useState } from 'react'; export default function TrafficLight() { const [walk, setWalk] = useState(true); function handleClick() { setWalk(!walk); } return ( <> <button onClick={handleClick}> Change to {walk ? 'Stop' : 'Walk'} </button> <h1 style={{ color: walk ? 'darkgreen' : 'darkred' }}> {walk ? 'Walk' : 'Stop'} </h1> </> ); } 复制代码
向单击处理程序添加 alert。当绿灯亮并显示“Walk,”时,点击按钮应该显示“Stop is next.”。当红灯亮并显示“Stop,”时,点击按钮应该显示“Walk is next.”。
把 alert 放在 setWalk
调用之前还是之后有区别吗?
3
2
1
解决方式:
import { useState } from 'react'; export default function TrafficLight() { const [walk, setWalk] = useState(true); function handleClick() { setWalk(!walk); alert(walk ? 'Stop is next' : 'Walk is next'); // 这里 } return ( <> <button onClick={handleClick}> Change to {walk ? 'Stop' : 'Walk'} </button> <h1 style={{ color: walk ? 'darkgreen' : 'darkred' }}> {walk ? 'Walk' : 'Stop'} </h1> </> ); } 复制代码
把它放在 setWalk
调用之前还是之后都没有区别,这次 render 的 walk
值是固定的。调用 setWalk
只会在下一次 render 更改它,但不会影响上一次 render 的事件处理程序。
这行代码乍一看似乎有悖常理:
alert(walk ? 'Stop is next' : 'Walk is next'); 复制代码
但是如果你把它读成:“如果红绿灯显示‘Walk now’,那么消息应该是‘Stop is next’。”事件处理程序中的 walk
变量与 render 的 walk
值匹配并且不会改变。
您可以通过替换变量的方法来验证这是否正确。当 walk
为 true
时,你会得到:
<button onClick={() => { setWalk(false); alert('Stop is next'); }}> Change to Stop </button> <h1 style={{color: 'darkgreen'}}> Walk </h1> 复制代码
因此,单击“Change to Stop”会将 walk
设置为 false
的渲染进行排队,并 alert “Stop is next”。
伪原创工具 SEO网站优化 https://www.237it.com/
作者:小十七_
链接:https://juejin.cn/post/7035501818989772836