React16源码: React中context-stack的源码实现

React-navigation StackNavigator 使用攻略 目前的项目迭代进展到使用navigation来串联不同的screen,但是在涉及到对navigationOptions进行定制的时候由于版本的问题,网上的很多资料其实都是已经过时了的(有些则是并不相干)。本文针对RN 0.44,React-navigation   ^1.0.0-beta.11,进行navigationOptions的解释。        首先是navigationOptions 阅读详情

context-stack


1 ) 概述

  • 在 context 内部有一个概念是 stack
    • 有一个唯一的stack
    • 里面保存各种各样的东西
  • stack的特性
    • 在更新节点的时候,会把相关的信息入栈
      • 在因为stack就是栈,在里面会存储各种各样的信息
      • 在更新节点的时候,每一个节点的信息都会推入这个stack
    • 完成节点更新的时候,相关的信息需要出栈
      • 因为栈是一个先入后出的这么一个数据结构
      • 这正好对应于 react的更新过程中的 beginWork 是从头到尾
      • 沿着子树的一侧这么下来的一个过程,这个时候我们从头到尾,推入了相关的信息
      • 然后在 completeUnitOfWork 的时候,我们又是从尾到头去进行一个完成节点更新的操作
      • 这个时候刚好是一个相反的顺序
      • 在这个相反的顺序当中,又可以同时出栈,这样的话, 就可以保证我们的栈从更新开始到最终更新结束
      • 因为从更新开始到更新结束,都是要回到 root 节点,它这个栈更新开始的时候是空的
      • 更新结束的时候,也刚好变成一个空的状态
      • 这就是在更新时入栈,在完成节点时出栈
    • 在这个栈的数据结构中可以用不同的cursor来记录不同的信息
      • react的这个stack的实现过程中,它需要存的信息是非常多的
      • 比如说有新的 contextAPI 也有老的 contextAPI
      • 还有跟 HostComponent 相关的一些信息,还有container相关的一些信息
      • 这些信息之间是互不干涉,没有任何关联的,这些信息都要存在同一个stack里面
      • 通过 cursor 去标记这些相关性的信息自己处于哪个位置

2 )源码

定位到 packages/react-reconciler/src/ReactFiberStack.js

/**
 * Copyright (c) Facebook, Inc. and its affiliates.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 *
 * @flow
 */

import type {Fiber} from './ReactFiber';

import warningWithoutStack from 'shared/warningWithoutStack';

export type StackCursor<T> = {
  current: T,
};

const valueStack: Array<any> = [];

let fiberStack: Array<Fiber | null>;

if (__DEV__) {
  fiberStack = [];
}

let index = -1;

function createCursor<T>(defaultValue: T): StackCursor<T> {
  return {
    current: defaultValue,
  };
}

function isEmpty(): boolean {
  return index === -1;
}

function pop<T>(cursor: StackCursor<T>, fiber: Fiber): void {
  if (index < 0) {
    if (__DEV__) {
      warningWithoutStack(false, 'Unexpected pop.');
    }
    return;
  }

  if (__DEV__) {
    if (fiber !== fiberStack[index]) {
      warningWithoutStack(false, 'Unexpected Fiber popped.');
    }
  }

  cursor.current = valueStack[index];

  valueStack[index] = null;

  if (__DEV__) {
    fiberStack[index] = null;
  }

  index--;
}

function push<T>(cursor: StackCursor<T>, value: T, fiber: Fiber): void {
  index++;

  valueStack[index] = cursor.current;

  if (__DEV__) {
    fiberStack[index] = fiber;
  }

  cursor.current = value;
}

function checkThatStackIsEmpty() {
  if (__DEV__) {
    if (index !== -1) {
      warningWithoutStack(
        false,
        'Expected an empty stack. Something was not reset properly.',
      );
    }
  }
}

function resetStackAfterFatalErrorInDev() {
  if (__DEV__) {
    index = -1;
    valueStack.length = 0;
    fiberStack.length = 0;
  }
}

export {
  createCursor,
  isEmpty,
  pop,
  push,
  // DEV only:
  checkThatStackIsEmpty,
  resetStackAfterFatalErrorInDev,
};
  • 首先定义一个非常重要的变量叫做 valueStack,它是一个数组
  • 接下去这边有一个 fiberStack,它只是用于开发的过程当中, 可以先忽略它
  • 定义一个全局 index
    • 注意这个 index 就是对应 valueStack 目前存数据存在的哪个位置
  • 接下去, 声明了一个方法叫做 createCursor
    • 直接 return 了一个新的对象
    • 这个对象里面有一个 current 属性
    • 在创建的时候传入的一个 defaultValue 给 current 赋值
    • 它是一个 pure 的对象,没有任何其他的一些特性
  • 注意
    • 这整个文件,它对应的是一个模块
    • valueStack 定义一些什么东西
    • 它里面的所有的数据都是有关联性的
    • 主要的数据也就是 valuestack 跟 index 是在这个模块里面
    • 它其他的数据都是在外部,使用的时候才会创建的
    • 这个 index 它本来是标记 valueStack 对应数据存在哪个位置
    • 可以通过它是否等于 -1 来判断我们目前的 valueStack 它是否是一个空的数组
  • 接下去的 pop 方法
    • 如果 index < 0
      • 说明 valueStack 里面没有任何的数据,直接return
      • 因为我们没有任何东西是可以推出来的
    • 读取 index 在 valueStack 对应的 value 存入 cursor.current
      • 因为在推入的时候,就是把老的值存到 valueStack上面,然后新的值它等于新设置的值
      • 如果要 pop 的时候,对应的肯定要把老的那个值再赋值回来
    • 将 index 对应在 valueStack 中的 value 置空
    • 将 index –
  • 接下去的 push 方法
    • 它接收的参数 cursor, value, fiber
    • cursor 是通过 createCursor 这个方法来创建的一个游标对象
    • 将 index ++
    • 将老的 value (cursor.current) 推入到 栈 当中
    • 将当前 cursor.current 指向传进来的 value
    • 注意,在一次 push 中新的 value 不会入栈的
  • checkThatStackIsEmpty
    • 这个只有在开发时会用到,其实就跟 isEmpty 是一样的
    • 它判断一下index是否等于 -1,然后进行一个warning
  • resetStackAfterFatalErrorInDev
    • dev 相关变量,无需过多关注
    • 就是重置了一些值
  • 注意
    • 如果在对 valueStack 进行操作的过程中,顺序是不一样的
    • 比如说,我有三种不同的数据类型,就有三个不同的cursor
    • 3个不同的 cursor 它们推入的这些数据,保存的不一样
    • 比如说,我目前这个数组先推入了一个a,然后再推入了一个b,然后再推入了一个c
    • 它们分别对应的是 cursor1(c1), cursor2(c2), cursor3(c3),它们想要读取的数据应该是这样的
    • 即 [a, b, c] => c1, c2, c3
    • 在 pop 的时候,可能先 pop 了 c1,但是我拿到的是却是 c3 对应的数据 c
    • 这个就是我们不想要出现的一个情况,实际上这个文件内没有解决这个问题
    • 因为react在更新的过程当中,先从 beginWork 里面推数据
    • 然后在 completeUnitOfWork 里面去提出数据
    • 这个过程中,它始终保持着 cursor 的一一对应关系
    • 也就是说我推进来的是c1, c2, c3的顺序
    • 推出的时候,要先推出 c3,再推出 c2,再推出 c1
    • 它们拿到的值都是一个一一对应的关系
    • 这是react在使用这个stack模块的时候去控制的
    • 而不是在我们这个模块内部去解的这个问题
    • 比如说 context 它一个入栈,出栈的一个情况的时候就会有这个调用的过程
    • 这个目前先跳过
React Context API 原理深度解析:不是状态管理,而是渲染引擎级通信机制 Context API 是 React 16.3 引入的跨层级数据传递基础设施,其本质并非状态管理工具,而是基于 Fiber 架构构建的上下文绑定机制。它通过特殊的 fiber tag(ContextProvider)、依赖链表(contextDependencies)和位掩码(changedBits)实现细粒度更新调度,使 context 消费具备 O(1) 读取性能与可中断渲染能力。相比 Redux 等应用层状态库,Context 的技术价值在于零开销的环境配置分发(如 theme、locale、aut 阅读详情

相关推荐

OpenCode Agent模式:ReAct协议驱动的AI工程师工作流

Agent并非功能开关,而是现代AI编程工具中内嵌的智能执行范式。其核心源于ReAct(Reasoning + Acting)理论,将传统命令行操作升维为‘观察→推理→行动→验证’的闭环决策流程。该模式依赖三大技术支柱:结构化上下文感知的Observe、双通道置信校验的Reason、受控接口约束的Act,以及可追溯的Verify机制。在工程实践中,它显著提升React组件审计、代码修复、性能诊断等场景的自动化深度与可信度。OpenCode通过Skill系统封装领域能力,以Context Graph构建记忆网

cumo7370的博客 444

React Navigation 入门(三) - StackNavigator 属性详解

本节主要讲 StackNavigator 与定义相关的详细属性。在新的页面被放入栈顶之后,StackNavigator 给你的应用程序提供了切换页面的方法。在 iOS 与 Android 平台上,StackNavigator 默认对应着它们各自的风格,比如在 iOS 上新的页面从右侧滑入,而在 Android 上则是从底部淡入。

王小北的技术博客 8376

单细胞转录组聚类分析R包——SC3的应用

前言 在做单细胞相关聚类分析的过程中,为了研究异质性,发现了一种专门用于单细胞转录组的聚类分析R包——SC3(single cell consensus clustering,单细胞一致性聚类)。该聚类算法发表于Nature Methods(2017),能够让单细胞RNA-seq基于转录组特征对细胞类型进行定量表征。这是一种用户友好的无监督聚类工具,它通过一致方法将多个聚类解决方案组合在一起,从而得到高精度和鲁棒性的分群结果。SC3包的官方具体使用教程见:http://www.bioconductor.or

m0_51042606的博客 5005

Stacks 项目使用教程

Stacks 是一个基于 React 的 UI 组件库,旨在帮助开发者快速构建现代化的 Web 应用程序。它提供了丰富的 UI 组件和布局工具,支持响应式设计,并且易于集成到现有的 React 项目中。Stacks 的设计理念是简洁、灵活和高效,适合各种规模的项目。 ## 2. 项目快速启动 ### 安装 首先,确保你已经安装了 Node.js 和 npm。然后,通过 npm 安装 Stac...

gitblog_00444的博客 998

用户行为数据分析 User Behavior Data from Taobao for Recommendation

一、提出问题 二、理解数据 数据来源 阿里云天池数据集:(https://tianchi.aliyun.com/dataset/dataDetail?dataId=649) 本文选取的数据集为UserBehavior.csv,共有5242880条数据。数据的具体类别如下表所示: 用户行为种类有四种,如下表所示 对于数据维度的说明如下: 在本文选取的2017年11月25日到2017年12月3日的时间范围内,不重复的用户数量为10202,不重复的商品ID数为412369,不重复的商品类目ID数为5859,

cccxxxqq的博客 5207

2025年再论 SAP ABAP 系统经典的三层架构的理解

【摘要】本文基于作者19年SAP开发经验,深入解析SAP经典三层架构在S/4HANA时代的演进与实践。数据库层从多数据库支持转向HANA专属,通过SQLScript实现计算下推;应用层以ABAP平台为核心,融合OData和RAP等现代开发范式;表现层从SAP GUI过渡到Fiori Launchpad为主导。文章通过真实案例(如月末关账优化、ATP检查改造)展示三层协作如何提升性能,并探讨了本地/云/混合部署策略。全文贯穿SAP官方技术文档参考,为开发者提供体系化架构认知和实践指导。

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 757

React Redux Quick Start 实战指南:安装、Provider 与 connect() 入门

React Redux 是 Redux 官方的 React 绑定库,它让 React 组件能够从 Redux store 中读取数据,并向 store dispatch action 来更新数据。本文以 React Redux 6.x 的 Quick Start 指南为核心,系统讲解从安装、通过 `<Provider />` 注入 store,到使用 `connect()` 连接组件的完整流程,并

gitblog_01025的博客 1041

-bash: mysql: 未找到命令

解决问题,😀

知识改变命运,ヾ(◍°∇°◍)ノ゙【求关注】 1350

React面试核心:Fiber架构与Hooks原理深度解析

React作为现代前端开发的核心框架,其Fiber架构和Hooks机制是理解框架设计的关键。Fiber架构通过任务分片和优先级调度实现了高性能渲染,而Hooks的链表存储机制则革新了状态管理方式。这些底层原理不仅决定了React应用的性能表现,也是面试中区分工程师水平的重要标尺。在实际开发中,合理应用React.memo、useMemo等优化手段能有效解决组件重渲染问题,而useEffect的清理机制则是避免内存泄漏的核心。从虚拟DOM diff算法到Server Components等前沿特性,掌握Rea

chuannaoxuan4674的博客 380

使用 Simulink 进行电力电子系统的大信号模型仿真

电力电子系统(Power Electronics System)包括各种功率转换器(如 DC-DC 转换器、逆变器等)。这些设备中的关键组件(如 MOSFET、IGBT、电容器、电感器等)不仅影响系统的性能,还直接关系到系统的稳定性、效率和可靠性。因此,在设计阶段进行详细的建模和仿真至关重要。大信号模型仿真的目的是通过模拟系统在非线性条件下的真实行为,评估其瞬态响应、稳态性能以及对不同负载和输入电压变化的响应。通过本教程,我们介绍了如何使用 Simulink 进行电力电子系统的大信号模型仿真。背景介绍。

xiaoheshang_123的博客 305

Bean named‘ddlApplicationRunner‘is expected to be of type ‘org.springframework.boot.Runner‘

springboot3.1.7整合mybatisplus3.5.3.2版本报错,sringboot3.x整合myabtis报错

雾林小妖的博客 1万+

react-admin TextArrayField 组件完全指南:用 MUI Chip 优雅展示数组字段

`<TextArrayField>` 是 react-admin 中专门用于在详情视图(Show)、编辑视图(Edit)或自定义字段布局里渲染标量数组(如 `genres`、`tags` 等)的展示型字段组件。它基于 Material-UI 的 `Stack` 与 `Chip` 构建,把数组中的每个元素渲染为一个小巧的标签,既节省垂直空间又提升了可读性。读完本文,你将掌握 `<TextArrayF

gitblog_00663的博客 1133

机器人控制基础:伺服驱动器的泄放电阻

摘要:伺服驱动器泄放电阻用于消耗电机减速或制动时产生的再生电能,防止母线电压过高损坏元件。其核心作用是将多余电能转化为热能,规避硬件损坏和停机风险。选型需关注功率、阻值和封装三大参数,功率应匹配再生能量,阻值需符合驱动器要求,封装应满足散热需求。可通过动态监测母线电压或静态检测电阻阻值来判断其是否正常工作。

start_up_go的博客 384

Full-Stack React Projects Modern web development using React 16, Node, Express, and MongoDB学习笔记

使用Json Web Token。

多看多听多总结 558

lwip-2.0.3

lwip是瑞典计算机科学院(SICS)的Adam Dunkels 开发的一个小型开源的TCP/IP协议栈。实现的重点是在保持TCP协议主要功能的基础上减少对RAM 的占用。

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

深入调试 Prepack React 编译器:fb-www 环境实战指南

本文基于 Prepack 仓库中的 [fb-www/README.md](https://link.gitcode.com/i/407e45bfd06a0da0b92d00f801713007),完整讲解如何在 Prepack 驱动的 React 编译器原型上进行调试与测试。你将掌握从输入代码结构、命令行编译、VS Code 断点调试到聚焦式测试运行的一整套工作流,并理解 `__evaluateP

gitblog_01170的博客 998

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

Midway serverless-http-parser 全解析:从 API 网关事件到 Koa Context 的桥接实现与版本演进

`@midwayjs/serverless-http-parser` 是 Midway 无服务(Serverless)体系中最底层的"翻译官":它把阿里云、腾讯云、AWS 等平台 API 网关(API Gateway / APIGW)的触发器事件(trigger event)解析为开发者熟悉的 Koa 风格 `ctx` 对象,让同一套 Web 业务代码可以无缝跑在函数计算(FC / SCF / L

gitblog_00067的博客 216

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

React Native 架构实战:Expo 路由、认证、离线优先与原生集成的生产级模式——agents 仓库 react-native-architecture 技能全解

本篇技术指南以 agents 仓库中 `frontend-mobile-development` 插件的 `react-native-architecture` 技能为核心,系统拆解六个可直接复用的生产级 React Native / Expo 架构模式:Expo Router 导航、认证流程、离线优先数据层、原生模块集成、平台特定代码与列表性能优化,并覆盖从 EAS 云构建到应用商店提交、OTA

gitblog_00392的博客 438

React Redux 贡献指南:从 Issue 报告到 PR 合并的完整开发者工作流

本文是 React Redux 官方仓库的《Contributing》指南深度展开版,围绕社区贡献的完整闭环展开:如何报告 Issue、如何搭建 pnpm 开发环境、如何构建多格式产物、如何运行 Vitest 测试与 oxlint 检查,以及如何以正确姿势提交 Pull Request。读完本文,你将掌握一套可直接照抄执行的 React Redux 源码贡献流程,并对 `pnpm build`、`

gitblog_00606的博客 26

rsi-jev-v6.1-vl-27b是怎么炼成的:两个LoRA微调的Model Soup权重平均与9轮基准验证全记录

rsi-jev-v6.1-vl-27b 是一款基于 Qwen3.8-27B 的多模态类型化决策模型(System One):它把同一父模型的两次 LoRA 微调做 Model Soup 权重平均,在第 48、56、64 层各设一个决策头实现早退,一次前向就给每个选项打出概率——Decision Index 0.3 公开集拿到 65.64 分,bf16 下单张 96GB 显卡即可运行。下文完整记录它

gitblog_00454的博客 456

Eclipse Theia 升级迁移指南:从 ESBuild 打包、React 19 到 AI 配置体系重构的完整实操手册

本文是基于仓库内官方迁移文档([doc/Migration.md](https://link.gitcode.com/i/663b86c250c46ab9709557710145f233))整理的 Eclipse Theia 升级实战指南。它面向正在跟随 Theia 版本演进而维护自身应用的 adopters(扩展开发者与产品集成方),系统梳理了从最新主干的 AI 配置视图重构、ESBuild 统

gitblog_00926的博客 350

react-native-video 生命周期管理:跨导航与 App 后台的播放控制实战(v6 & v7)

本文围绕 react-native-video 在 React Navigation 多屏导航与 App 前后台切换下的播放生命周期展开:从 React Navigation 的「detach ≠ unmount」机制讲起,给出离开页面停播、切 Tab 防黑屏/防重启、跨屏保活的全局播放器、后台续播以及信息流「单实例播放」的完整方案,并逐一结合本仓库源码([useVideoPlayer.ts](h

gitblog_00838的博客 139

Valdi 迁移指南:从 Flutter、React 与 Jetpack Compose 到 Valdi 的组件模型映射实战

Valdi 是一套跨平台 UI 框架,以 TypeScript 类组件 + JSX 声明式渲染为核心,覆盖 iOS、Android 与 macOS。本文以 [ai-skills/skills/valdi-migrate/skill.md](https://link.gitcode.com/i/8ea2cef4b5581a7ea3e444da66025b4d) 为骨架,系统讲解将 Flutter W

gitblog_00029的博客 1035

react-sketchapp API 完全参考:render、组件、Hooks、StyleSheet 与 Symbols 实战指南

> **导读**:本文是 [docs/API.md](https://link.gitcode.com/i/8a9447933efeb90f0aa52d95dcb9b4eb) 的深度讲解版,围绕 react-sketchapp 面向开发者的全部公共 API 展开——从顶层 `render` / `renderToJSON` 入口,到 `<Document>`、`<Page>`、`<Artboard

gitblog_01013的博客 1074

调用栈溢出排查指南:从原理到Call Stack Diffs实战

在JavaScript开发中,调用栈(Call Stack)是一本记录函数调用顺序的实时台账,也是排查递归、循环引用等运行时问题的核心线索。当程序出现Maximum call stack size exceeded这类栈溢出错误时,往往意味着某个递归缺少终止条件,或数据结构中存在环状引用,导致函数帧无限压栈。理解调用栈的工作原理,有助于开发者快速定位性能瓶颈与异常递归。Call Stack Diffs是一种比“看栈”更高效的“比栈”技巧,通过对比正常与异常时刻的栈快照,差异帧能直接暴露问题入口。结合Vue中

weixin_33924770的博客 362

Vibe Coding 中的 Context 管理实战:三层上下文体系与项目级持久化(vibe-vibe 教程精讲)

Context(上下文)是 Vibe Coding 中最容易被忽视、却最直接影响 AI 输出质量的变量。本文基于 vibe-vibe 开源教程 [1.4.4 Context 管理技巧](https://link.gitcode.com/i/c225290581f1f050a02ceba99ac9ec36) 展开,结合教程中 [1.4 Vibe vs Spec](https://link.gitco

gitblog_01175的博客 105
上一篇: React16源码: React中commit阶段的commitAllLifeCycles的源码实现
下一篇: React16源码: React中LegacyContext的源码实现
Wang's Blog
博客等级 码龄12年 7438粉丝 2421原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Wang's Blog

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值