Skip to content
On this page

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"}

总结

  1. useState其实也是一个useReducer hook,只是内部内置了baseStateReducer函数
  2. 初次渲染,走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上
  3. 点击按钮时调用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上

Released under the MIT License.