5. React18 - useState
示例
jsx
import * as React from 'react';
import { createRoot } from "react-dom/client";
function FunctionComponent() {
const [number, setNumber] = React.useState(0);
return <button onClick={() => {
setNumber(number => number + 1)//0
}}>{number}</button>
}
let element = <FunctionComponent />
const root = createRoot(document.getElementById("root"));
root.render(element);
实现原理
详细流程图:https://app.diagrams.net/#G1_bOuJ9OdaQQhLKgCo6XtW_p6onKr-Mkm#{"pageId"%3A"gINCcu49F0h3ws6Z-8CI"}
总结
- useState其实也是一个useReducer hook,只是内部内置了baseStateReducer函数
- 初次渲染,走mount流程
- 构建Fiber树
- 创建Function component fiber时,建立ReactCurrentDispatcher.current与HooksDispatcherOnMount的关联
- 执行Function Component 函数,执行React.useState(HooksDispatcherOnMount),构建fiber的hook 单向链表
- hook.memoizedState放置initial初始值,同时hook.queue.lastRenderedReducer = baseStateReducer
- jsx 就直接引用useState 返回的number值,jsx通过bebal 转义变成Vdom,此时使用的就是newState值,对应的属性也会挂载至Vdom的props上
- 点击按钮时调用dispatchSetState 的派发方法
- 执行hook.queue中的lastRenderedReducer拿到最新的newsState,然后将其挂载至update.eagerState上
- 重新从root开始构建新的fiber树
- 建立ReactCurrentDispatcher.current与HooksDispatcherOnUpdate 的关联
- 执行Function Component 函数,执行React.useState(HooksDispatcherOnUpdate ),updateReducer 从hasEagerState拿到最新的newState
- 最后jsx通过bebal 转义变成Vdom,此时使用的就是newState值,对应的属性也会挂载至Vdom的props上