React源码 ReactContext
import React from 'react'
import PropTypes from 'prop-types' const { Provider, Consumer } = React.createContext('default') class Parent extends React.Component {
state = {
childContext: '123',
newContext: '456',
} getChildContext() {
return { value: this.state.childContext, a: 'aaaaa' }
} render() {
return (
<>
<div>
<label>childContext:</label>
<input
type="text"
value={this.state.childContext}
onChange={e => this.setState({ childContext: e.target.value })}
/>
</div>
<div>
<label>newContext:</label>
<input
type="text"
value={this.state.newContext}
onChange={e => this.setState({ newContext: e.target.value })}
/>
</div>
<Provider value={this.state.newContext}>{this.props.children}</Provider>
</>
)
}
} class Parent2 extends React.Component {
// { value: this.state.childContext, a: 'bbbbb' }
getChildContext() {
return { a: 'bbbbb' }
} render() {
return this.props.children
}
} function Child1(props, context) {
console.log(context)
return <Consumer>{value => <p>newContext: {value}</p>}</Consumer>
} Child1.contextTypes = {
value: PropTypes.string,
} class Child2 extends React.Component {
render() {
return (
<p>
childContext: {this.context.value} {this.context.a}
</p>
)
}
} // Child2.contextType = Consumer Child2.contextTypes = {
value: PropTypes.string,
a: PropTypes.string,
} Parent.childContextTypes = {
value: PropTypes.string,
a: PropTypes.string,
} Parent2.childContextTypes = {
a: PropTypes.string,
} export default () => (
<Parent>
<Parent2>
<Child1 />
<Child2 />
</Parent2>
</Parent>
)
export default () => (
<Parent>
<Parent2>
<Child2 />
</Parent2>
</Parent>
)
首先组件层级是这样的,这里 child2 子级要使用 parent 的数据。要使用 childContextType,必须先声明
Parent.childContextTypes = {
value: PropTypes.string,
a: PropTypes.string,
}
getChildContext() {
return { value: this.state.childContext, a: 'aaaaa' }
}
Child2.contextTypes = {
value: PropTypes.string,
a: PropTypes.string,
}
render() {
return (
<p>
childContext: {this.context.value} {this.context.a}
</p>
)
}
const { Provider, Consumer } = React.createContext('default')
<Provider value={this.state.newContext}>{this.props.children}</Provider>
<Consumer>{value => <p>newContext: {value}</p>}</Consumer>
import {REACT_PROVIDER_TYPE, REACT_CONTEXT_TYPE} from 'shared/ReactSymbols';
import type {ReactContext} from 'shared/ReactTypes';
import warningWithoutStack from 'shared/warningWithoutStack';
import warning from 'shared/warning';
export function createContext<T>(
defaultValue: T,
calculateChangedBits: ?(a: T, b: T) => number,
): ReactContext<T> {
if (calculateChangedBits === undefined) {
calculateChangedBits = null;
} else {
if (__DEV__) {
warningWithoutStack(
calculateChangedBits === null ||
typeof calculateChangedBits === 'function',
'createContext: Expected the optional second argument to be a ' +
'function. Instead received: %s',
calculateChangedBits,
);
}
}
const context: ReactContext<T> = {
$$typeof: REACT_CONTEXT_TYPE,
_calculateChangedBits: calculateChangedBits,
_currentValue: defaultValue,
_currentValue2: defaultValue,
// These are circular
Provider: (null: any),
Consumer: (null: any),
};
context.Provider = {
$$typeof: REACT_PROVIDER_TYPE,
_context: context,
};
context.Consumer = context;
return context;
}
我们看到 createContext ,他接收的是一个 defaultValue ,还有一个是 calculateChangedBits 。是一个方法,是用来计算新老 context 的一个变化的。方法里面看到他声明了一个 context 对象,这个对象跟之前看的 ReactElement 非常的像。也有一个 $$typeof ,这个 $$typeof 跟 ReactElement 的 $$typeof 是不一样的。还有两个属性 _currentValue , _currentValue2 这两个属性是一样的,只是用到的地方不一样。 _currentValue 这个 value 是用来记录 Provider 里面的这个 value 。 他有变化的情况下就会更新到这个 _currentValue 。这就是用来记录最新的 context 的值的, 下面会有个 Provider 和 Consumer 。
React源码 ReactContext的更多相关文章
- React源码剖析系列 - 生命周期的管理艺术
目前,前端领域中 React 势头正盛,很少能够深入剖析内部实现机制和原理.本系列文章希望通过剖析 React 源码,理解其内部的实现原理,知其然更要知其所以然. 对于 React,其组件生命周期(C ...
- React源码解析:ReactElement
ReactElement算是React源码中比较简单的部分了,直接看源码: var ReactElement = function(type, key, ref, self, source, owne ...
- react 源码之setState
今天看了react源码,仅以记录. 1:monorepo (react 的代码管理方式) 与multirepo 相对. monorepo是单代码仓库, 是把所有相关项目都集中在一个代码仓库中,每个mo ...
- React 源码剖析系列 - 不可思议的 react diff
简单点的重复利用已有的dom和其他REACT性能快的原理. key的作用和虚拟节点 目前,前端领域中 React 势头正盛,使用者众多却少有能够深入剖析内部实现机制和原理. 本系列文章希望通过剖析 ...
- React 源码剖析系列 - 生命周期的管理艺术
目前,前端领域中 React 势头正盛,很少能够深入剖析内部实现机制和原理. 本系列文章 希望通过剖析 React 源码,理解其内部的实现原理,知其然更要知其所以然. 对于 React,其组件生命周期 ...
- 读react源码准备
git源码地址:https://github.com/facebook/react react 里面就是 react源码 react里面的react文件夹就是react源码,react源码非常的少,总 ...
- react源码之render
1.最近学习react源码,刚刚入门,看了render的原理,到了fiberRoot的创建 如图:
- React躬行记(16)——React源码分析
React可大致分为三部分:Core.Reconciler和Renderer,在阅读源码之前,首先需要搭建测试环境,为了方便起见,本文直接采用了网友搭建好的环境,React版本是16.8.6,与最新版 ...
- React源码之组件的实现与首次渲染
react: v15.0.0 本文讲 组件如何编译 以及 ReactDOM.render 的渲染过程. babel 的编译 babel 将 React JSX 编译成 JavaScript. 在 ba ...
随机推荐
- Affy包 estrogen包
下载安装 if (!requireNamespace("BiocManager", quietly = TRUE)) install.packages("BiocMana ...
- helm repository 相关
chart repo是一个可用来存储index.yaml与打包的chart文件的HTTP server.当要分享chart时,需要上传chart文件到chart仓库,任何一个能够提供yaml与tar文 ...
- 安装OpenIMSCore的SIP测试客户端 utcimsclient
环境 Ubuntu16.04,Vmvare12(win10). 下载 & 解压 //utcimsclient 下载地址 : https://liquidtelecom.dl.sourcefor ...
- rent a apartment
今日焦点 month-to-month 按月 6-month minimum 至少六个月 sublease 转租 drenched in sunlight 阳光充足的 词汇实践 I am lookin ...
- ng 手机验证码验证/发送(含倒计时)
ng 的手机号码进行验证: 1.在对应的ts文件中,先声明一个变量 private mobile: string private btnCaptchaText: string = '发送验证码' ...
- Oracle 层次查询 connect by
oracle 层次查询 语法: SELECT ... FROM [WHERE condition] --过 ...
- 【C++】虚函数的实现机制
一.什么是虚函数? 虚函数是在类中由virtual关键字声明的成员函数,并且每一个含有虚函数的类都至少有一个与之对应的虚函数表,其中存放着该类所有虚函数对应的函数指针 在基类中进行如下定义: virt ...
- SocketChannel简述
前言 在前面的Channel概述的分类中提到过SocketChannel主要是用来基于TCP通信的通道.这篇文章详细介绍下SocketChannel SocketChannel是什么 SocketCh ...
- .NET / C# 时间与时间戳的转换
时间戳是指格林威治时间1970年01月01日00时00分00秒(北京时间1970年01月01日08时00分00秒)起至现在的总毫秒数. 我们在计算时间戳时应为1970年01月01日到指定时间. 应当注 ...
- java之maven之maven的使用
这里使用的工具是 myeclipse ,所以这里讲的是在 myeclipse 上使用maven. 1.什么是仓库? 用于存放依赖包.配置文件.其他插件等. 项目添加依赖时,默认从 本地仓库 读取依赖包 ...