React 实现 useState

本文将带大家实现 useState。

先看下如何使用。

js 复制代码
function FunctionComponent() {
  const [count1, setCount1] = useState(1);

  return (
    <div className="border">
      <button
        onClick={() => {
          setCount1(count1 + 1);
        }}
      >
        {count1}
      </button>
    </div>
  );
}

ReactDOM.createRoot(document.getElementById("root") as HTMLElement).render(
  (<FunctionComponent />) as any
);

useState 是基于 useReducer 实现的,参考文章 React 实现 useReducer

实现 useState

js 复制代码
// 源码中 useState 与 useReducer 对比:
// useState 如果 state 没有改变,不引起组件更新。useReducer 不是如此。(老的源码中,state 没有改变,两者都不更新)
// reducer 代表 state 修改规则,useReducer 比较方便复用这个规则
export function useState<S>(initialState: (() => S) | S) {
  const init = isFn(initialState) ? (initialState as any)() : initialState;
  return useReducer(null, init);
}

useReducer 修改

为了适配 useStateuseReducerdispatchReducerAction 两个函数的 reducer 参数增加了 null。

js 复制代码
export function useReducer<S, I, A>(
  reducer: ((state: S, action: A) => S) | null,
  initialArg: I,
  init?: (initialArg: I) => S
) {
    ...
}

function dispatchReducerAction<S, I, A>(
  fiber: Fiber,
  hook: Hook,
  reducer: ((state: S, action: A) => S) | null,
  action: any
) {
    ...
}

再聊 scheduleUpdateOnFiber

Fiber hooks 调用 scheduleUpdateOnFiber 时,第三个参数传的都是 true。

因为 React 考虑到 ensureRootIsScheduled 使用到了调度器,会增加复杂度。

js 复制代码
export function scheduleUpdateOnFiber(
  root: FiberRoot,
  fiber: Fiber,
  isSync?: boolean
) {
  workInProgressRoot = root;
  workInProgress = fiber;

  if (isSync) {
    // queueMicrotask 是 JS 原生 API
    queueMicrotask(() => performConcurrentWorkOnRoot(root));
  } else {
    ensureRootIsScheduled(root);
  }
}

export function performConcurrentWorkOnRoot(root: FiberRoot) {
  // 1. render, 构建 fiber 树,即 VDOM(beginWork|completeWork)
  renderRootSync(root);

  const finishedWork = root.current.alternate;
  root.finishedWork = finishedWork; // 根 Fiber

  // 2. commit, VDOM -> DOM
  commitRoot(root);
}
相关推荐
jin12332216 分钟前
React Native鸿蒙跨平台剧本杀组队消息与快捷入口组件,包含消息列表展示、快捷入口管理、快捷操作触发和消息详情预览四大核心功能
javascript·react native·react.js·ecmascript·harmonyos
烬头88212 小时前
React Native鸿蒙跨平台实现二维码联系人APP(QRCodeContactApp)
javascript·react native·react.js·ecmascript·harmonyos
pas1362 小时前
40-mini-vue 实现三种联合类型
前端·javascript·vue.js
摇滚侠2 小时前
2 小时快速入门 ES6 基础视频教程
前端·ecmascript·es6
珑墨3 小时前
【Turbo】使用介绍
前端
军军君013 小时前
Three.js基础功能学习十三:太阳系实例上
前端·javascript·vue.js·学习·3d·前端框架·three
xiaoqi9224 小时前
React Native鸿蒙跨平台如何实现分类页面组件通过searchQuery状态变量管理搜索输入,实现了分类的实时过滤功能
javascript·react native·react.js·ecmascript·harmonyos
打小就很皮...4 小时前
Tesseract.js OCR 中文识别
前端·react.js·ocr
qq_177767374 小时前
React Native鸿蒙跨平台实现应用介绍页,实现了应用信息卡片展示、特色功能网格布局、权限/联系信息陈列、评分展示、模态框详情交互等通用场景
javascript·react native·react.js·ecmascript·交互·harmonyos
wuhen_n5 小时前
JavaScript内存管理与执行上下文
前端·javascript