React16源码: React中的setState和forceUpdate源码实现

setState 和 forceUpdate

1 ) 概述

  • 通过 class component 内部的 setState,以及 forceUpdate 去更新一个组件的过程
  • 在react的应用当中,我们只有 ReactDOM.render setState,以及 forceUpdate
  • 这几种种方式去更新react的应用是合理的,其他没有什么特别常用的方式去更新了
  • 而且react官方推荐的也是用这些。forceUpdate 其实本身也不是特别推荐的
  • 因为有比较特殊的作用,以及比较特殊的使用场合, 也算是一个比较有用的API
  • 在React16.7之后发布的Hooks, Hooks里面我们通过
  • useState 返回过来的一个方法,也可以去更新一个组件的状态
    • 这块看不到源码,只能看到打包之后的代码
    • 它的设置比较特殊,这块先跳过
  • setState,以及 forceUpdate的核心,首先是他们是给节点 Fiber 去创建更新的
  • 对于 ReactDOM.render 来说,它创建的 update 是放在root上面
  • 它是一个整体的渲染,因为执行 ReactDOM.render 的时候
  • 整个应用都没有任何的产生,任何的节点都没有生成,是一个初始的渲染
  • 所以 setStateforceUpdate 是针对某一个 class component 来说的
    • 这个 class component 的状态来进行更新
    • 把新的状态计算并渲染出来
  • setStateforceUpdate 两者更新的类型不同
    • 它们上面有 UpdateState, ForceUpdate 两种不同的 tag
    • 这个tag就对应的它们是更新的类型不同

2 )源码

  • 先跳过 组件如何去渲染

    • 也就是我们的 class component,什么时候会被实例化
    • 这个涉及到后面的更新的流程
  • 我们的component的BaseClass在初始化的时候会拿到一个update的这个对象

  • 这个对象来自于哪个地方

  • 源码: https://github.com/facebook/react/blob/v16.6.0/packages/react-reconciler/src/ReactFiberClassComponent.js

  • 这个文件中,有涉及很多 class 相关的代码

    js 复制代码
    const classComponentUpdater = {
      isMounted,
      enqueueSetState(inst, payload, callback) {
        const fiber = ReactInstanceMap.get(inst); // inst 是调用 this.setState 时的 this,在react渲染的时候会通过 `ReactInstanceMap` 做映射和获取 Fiber对象
        const currentTime = requestCurrentTime();
        const expirationTime = computeExpirationForFiber(currentTime, fiber);
    
        const update = createUpdate(expirationTime);
        update.payload = payload; // 这里 payload 是 setState时传入的对象
        if (callback !== undefined && callback !== null) {
          if (__DEV__) {
            warnOnInvalidCallback(callback, 'setState');
          }
          update.callback = callback; // 挂载 callback
        }
    
        enqueueUpdate(fiber, update); // 把fiber对象的updateQueue进行初始化或更新
        scheduleWork(fiber, expirationTime); // 进行调度处理
      },
      enqueueReplaceState(inst, payload, callback) {
        const fiber = ReactInstanceMap.get(inst);
        const currentTime = requestCurrentTime();
        const expirationTime = computeExpirationForFiber(currentTime, fiber);
    
        const update = createUpdate(expirationTime);
        update.tag = ReplaceState;
        update.payload = payload;
    
        if (callback !== undefined && callback !== null) {
          if (__DEV__) {
            warnOnInvalidCallback(callback, 'replaceState');
          }
          update.callback = callback;
        }
    
        enqueueUpdate(fiber, update);
        scheduleWork(fiber, expirationTime);
      },
      enqueueForceUpdate(inst, callback) {
        const fiber = ReactInstanceMap.get(inst);
        const currentTime = requestCurrentTime();
        const expirationTime = computeExpirationForFiber(currentTime, fiber);
    
        const update = createUpdate(expirationTime);
        update.tag = ForceUpdate;
    
        if (callback !== undefined && callback !== null) {
          if (__DEV__) {
            warnOnInvalidCallback(callback, 'forceUpdate');
          }
          update.callback = callback;
        }
    
        enqueueUpdate(fiber, update);
        scheduleWork(fiber, expirationTime);
      },
    };
    • 这里面主要关注, enqueueSetStateenqueueForceUpdate 这两个enqueue 方法几乎一样,两者区别 看 update.tag
    • 看了上面的源码,发现 和 react-reconciler/src/ReactFiberReconciler.js 中的 updateContainer 很像
      • 内部调用 updateContainerAtExpirationTime 接着调用 scheduleRootUpdate 在这里面都基本相似
  • 所以,在React中创建更新的过程都是差不多的,创建完更新后,进入队列,就会进行整个应用的更新

  • React 是一个非常纯粹的框架,所有的核心都是服务应用的整体更新的, 就是 scheduleWork 函数进入之后的整体更新流程

  • 这块在React整体的代码量中占据非常大的比例

相关推荐
冻感糕人~21 小时前
【珍藏必备】ReAct框架实战指南:从零开始构建AI智能体,让大模型学会思考与行动
java·前端·人工智能·react.js·大模型·就业·大模型学习
梦帮科技1 天前
Node.js配置生成器CLI工具开发实战
前端·人工智能·windows·前端框架·node.js·json
C澒1 天前
前端整洁架构(Clean Architecture)实战解析:从理论到 Todo 项目落地
前端·架构·系统架构·前端框架
C澒1 天前
Remesh 框架详解:基于 CQRS 的前端领域驱动设计方案
前端·架构·前端框架·状态模式
C澒1 天前
前端分层架构实战:DDD 与 Clean Architecture 在大型业务系统中的落地路径与项目实践
前端·架构·系统架构·前端框架
lbb 小魔仙1 天前
【HarmonyOS实战】React Native 鸿蒙版实战:Calendar 日历组件完全指南
react native·react.js·harmonyos
晚霞的不甘1 天前
守护智能边界:CANN 的 AI 安全机制深度解析
人工智能·安全·语言模型·自然语言处理·前端框架
LYFlied1 天前
从 Vue 到 React,再到 React Native:资深前端开发者的平滑过渡指南
vue.js·react native·react.js
AAA阿giao1 天前
从零拆解一个 React + TypeScript 的 TodoList:模块化、数据流与工程实践
前端·react.js·ui·typescript·前端框架
晚霞的不甘1 天前
Flutter for OpenHarmony 构建简洁高效的待办事项应用 实战解析
flutter·ui·前端框架·交互·鸿蒙