**解决祖孙之间组件传值**
**例子**
```
~~~
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:'aaa'}
}
render() {
return(
<React.Fragment>
<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})}
/>
<Provider
value={this.state.newContext}>
{this.props.children}
</Provider>
</div>
</React.Fragment>
)
}
}
class Child1 extends React.Component{
render() {
return(
<p>
childContext:{this.context.value}
{/*{this.context.a}*/}
</p>
)
}
}
function Child2(){
return<Consumer>{value =>
<p> newContext:{value} </p>
}</Consumer>
}
Child1.contextTypes = {
value:PropTypes.string,
a:PropTypes.string
};
Parent.childContextTypes={
value:PropTypes.string,
a:PropTypes.string
};
export default ()=>(
<Parent>
<Child2/>
<Child1/>
</Parent>
)
```
源码:
~~~
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 {
}
//calculateChangedBits计算新老context的变化的
const context: ReactContext<T> = {
$$typeof: REACT_CONTEXT_TYPE,
_calculateChangedBits: calculateChangedBits,
// As a workaround to support multiple concurrent renderers, we categorize
// some renderers as primary and others as secondary. We only expect
// there to be two concurrent renderers at most: React Native (primary) and
// Fabric (secondary); React DOM (primary) and React ART (secondary).
// Secondary renderers store their context values on separate fields.
_currentValue: defaultValue,
_currentValue2: defaultValue,
//_currentValue用来记录provider提供的value有变化更新到_currentValue 记录context的值的
// Used to track how many concurrent renderers this context currently
// supports within in a single renderer. Such as parallel server rendering.
_threadCount: 0,
// These are circular
Provider: (null: any),
Consumer: (null: any),
};
context.Provider = {
$$typeof: REACT_PROVIDER_TYPE,
_context: context,
};
let hasWarnedAboutUsingNestedContextConsumers = false;
let hasWarnedAboutUsingConsumerProvider = false;
context.Consumer = context;
return context;
}
~~~
- 说明
- react源码
- 问答
- 慕课网视频
- 第二章:基础知识
- 001.ReactElement
- 002.react-component
- 003.ref
- 004.forwardRef
- 005.context
- 006.concurrentMode
- 007.supense和lazy
- 008.hooks
- 009.children
- 010.memo
- 011.others
- 第三章:react的更新
- 001.react-dom-render
- 第四章:Fiber Scheduler
- 第五章:各类组件的Update
- 第六章:完成节点任务
- 第七章:commitRoot
- 第八章:功能详解:基础
- 第九章:suspense and priority
- 第十章:功能详解:Hooks
- 001.基础知识
- 002.hook
- 003.RootFiber
- 004. hydrate
- react
- 高阶组件
- react基础
- Github面试题目