☝️上文提及:可以通过组件中的重要信息是否由组件自身
state
还是外部prop
驱动来区分「受控组件」&「非受控组件」。
换言之,props
是对外的,state
是对内的
props
:只读,父组件通过props
传递给子组件其所需要的状态;子组件内部不能直接修改props
,只能在父组件中修改。state
:可变,是组件内部维护的一组用于反映组件UI变化的状态集合。
本篇会 ✓ 🇨🇳 总结 React 中的 state 状态
回顾一下1:
① react 有两种原因会导致组件的渲染,其中 State setter 函数 更新变量会触发 React 渲染组件;
② State 变量 用于保存渲染间的数据。
👀 State = 存放数据 + 触发重新渲染
存储数据
const [index, setIndex] = useState(0);
function handleClick() {
setIndex(i => i + 1);
}
index
的初始值被useState(0)
设置为0
;- state 变量 (
index
) 会保存上次渲染的值; - state setter 函数 (
setIndex
) 可以更新 state 变量并触发 React 重新渲染组件。
更新数据
更新对象
核心:把当前的数据复制到新对象中
const [person, setPerson] = useState({name: '', age: 0})
setPerson({
...person,
age: e.target.value // 只覆盖 age 字段
})
setPerson({
...person,
[e.target.name]: e.target.value // 动态命名
})
‼️注意:...
展开语法本质是是“浅拷贝”——它只会复制一层。这使得它的执行速度很快,但是也意味着当你想要更新一个嵌套属性时,你必须得多次使用展开语法2。
setPerson({
...person, // 复制其它字段的数据
artwork: { // 替换 artwork 字段
...person.artwork, // 复制之前 person.artwork 中的数据
city: 'New Delhi' // 但是将 city 的值替换为 New Delhi!
}
});
更新数组
核心:将 React state 中的数组视为只读的
每次要更新一个数组时,需要把一个新的数组传入 state 的 setting 方法中。
避免使用 (会改变原始数组) | 推荐使用 (会返回一个新数组) | |
---|---|---|
添加元素 | push ,unshift | concat ,[...arr] 展开语法(例子) |
删除元素 | pop ,shift ,splice | filter ,slice (例子) |
替换元素 | splice ,arr[i] = ... 赋值 | map (例子) |
排序 | reverse ,sort | 先将数组复制一份(例子) |
批量更新
在 开篇:通过 state 阐述 React 渲染
setInterval
示例中曾提及:一个 state 变量的值永远不会在一次渲染的内部发生变化。
React 会等到事件处理函数中的 所有 代码都运行完毕再处理你的 state 更新。
export default function Counter() {
const [number, setNumber] = useState(0);
return (
<>
<h1>{number}</h1>
<button onClick={() => {
setNumber(n => n + 1);
setNumber(n => n + 1);
setNumber(n => n + 1);
}}>+3</button>
</>
)
}
- React 会将更新函数依次加入队列,以便在事件处理函数中的所有其他代码运行后进行处理。
- 在下一次渲染期间,React 会遍历队列并给你更新之后的最终 state。
触发重新渲染
- 对于初次渲染, React 会使用
appendChild()
DOM API 将其创建的所有 DOM 节点放在屏幕上。 - 对于重渲染, React 将应用最少的必要操作(在渲染时计算!),以使得 DOM 与最新的渲染输出相互匹配。
React 仅在渲染之间存在差异时才会更改 DOM 节点。
示例3:有一个组件,它每秒使用从父组件传递下来的不同属性重新渲染一次。
‼️注意,文本不会在组件重渲染时消失。
export default function Clock({ time }) {
return (
<>
<h1>{time}</h1>
<input />
</>
);
}
状态与渲染树中的位置相关: 相同位置的相同组件会使得 state 被保留下来,否则会重置。关于此部分的详实,在下一篇专题讲述!
https://blog.csdn.net/ligang2585116/article/details/136219429 通过 state 阐述 React 渲染 ↩︎
https://react.docschina.org/learn/updating-objects-in-state#updating-a-nested-object 更新一个嵌套对象 ↩︎
https://react.docschina.org/learn/render-and-commit#step-3-react-commits-changes-to-the-dom React 把更改提交到 DOM 上 ↩︎