State的实现
我们知道,在 React 中,组件内部某些属性的值依靠对应的 state 进行储存记忆
useState 的唯一参数是 state 变量的初始值,每一次组件渲染时, useState 会返回一个数组,其中包含:
state变量,会保存上次渲染的值state setter函数,用于更新state变量的值
在实际运用中,state 是通过这样的步骤运行的
- **组件进行第一次渲染。**此时传入
useState的初始值作为state变量的值。 - **更新
state。**当调用state setter函数时,会传入一个新的state值,React现在记住新的值并进行下一步渲染。 - 组件的第二次渲染。 此时
useState的参数依然是初始值,但state setter使React记住了新值,所以会返回[newState, stateSetter]
关于UseState的工作原理
- 在 React 内部,为每个组件保存了一个数组,其中每一项都是一个 state 对。
- 它维护当前 state 对的索引值,在渲染之前将其设置为 “0”。
- 每次调用 useState 时,React 都会为你提供一个 state 对并增加索引值
useState 调用,state初始化
function Gallery() {
// 每次调用 useState() 都会得到新的 pair
const [index, setIndex] = useState(0);
const [showMore, setShowMore] = useState(false);
//...
}
在 useState 内部
let componentHooks = [];
let currentHookIndex = 0;
function useState(initialState) {
let pair = componentHooks[currentHookIndex];
//...
pair = [initialState, setState]
//...
componentHooks[currentHookIndex] = pair;
currentHookIndex++;
return pair;
}
依据传入的initialState进行初始化,在componentHooks 中存储pair,并更新currentHookIndex
使用setState进行 state 的更新
let componentHooks = [];
let currentHookIndex = 0;
function useState(initialState) {
let pair = componentHooks[currentHookIndex];
if (pair) {
// 非首次渲染,pair已经存在
// 将其返回并为下一次 hook 的调用做准备
currentHookIndex++;
return pair;
}
pair = [initialState, setState];
function setState(nextState){
//将新的值放入pair
pair[0] = nexxtState;
//UpdateDom将currentHookIndex赋值为0,保证了每一次更新的state都在initialState序号为零的位置
UpdateDom();
}
//存储pair用于之后的渲染
//并为下一次的hook调用做准备
componentHooks[currentHookIndex] = pair;
currentHookIndex++;
return pair;
}
DOM的渲染
function updateDOM() {
// 在渲染组件之前
// 重置当前 Hook 的下标
currentHookIndex = 0;
// 更新 DOM 的具体代码省略
//...
如果一个组件进行两次渲染,那么每个组件副本都会有独立的 state