React之Context

旧版

  • Context三步曲
    • 【1】父组件中定义childContextTypes上下文对象的属性类型
    class Father extends React.Component {
        static childContextTypes = {
            name:PropTypes.string,
            age:PropTypes.number,
            color:PropTypes.string,
            setColor:PropTypes.func
        }
        render(){
            return(
                <> <Son/> </> ); } } 复制代码
    • 【2】父组件中定义getChildContext函数返回真正的上下文对象
    class Father extends React.Component {
        ...
        constructor(){
            super();
            this.state = {
                color:'red'
            }
        }
        getChildContext(){
            return {
                name:'GuYan',
                age:'18',
                color:this.state.color,
                setColor:this.setColor
            }
        }
        ...
        setColor = (color) =>{
            this.setState({
                color:color
            })
        }
    }
    复制代码
    • 【3】子组件中定义contextTypes接收上下文对象的属性类型
    class Son extends React.Component{
        static contextTypes = {
            color:PropTypes.string,
            setColor:PropTypes.func,
            name:PropTypes.name
        }
        render(){
            return (
               <> <p style={{color:this.context.color}}>{this.context.name}</p> <button onClick={()=>{this.context.setColor('red')}}> Change Color To Red </button> <button onClick={()=>{this.context.setColor('green')}}> Change Color To Green </button> </> ) } } 复制代码

新版

类组件

  • Context三步曲
    • 【1】全局经过React.creactContext()建立ThemeContext对象
    import React, { Component } from 'react';
    const ThemeContext = React.createContext();
    复制代码
    • 【2】父组件中经过ThemeContext.Provider组件包裹,并在此组件的value属性上定义上下文对象
    class Father extends Component{
        constructor(props){
            super(props);
            this.state = {
                color:'red',
                name:'GuYan',
            }
        }
        render(){
            const contextValue = {
                color:this.state.color,
                setColor:this.setColor,
                name:this.state.name
            }
            return (
                <Theme.Provider value = {contextValue}> <Son/> </Theme.Provider> ) } setColor = (color) =>{ this.setColor({ color:color }) } } 复制代码
    • 【3】子组件中经过定义contextType属性对象为ThemeContext对象来接收上下文对象
    class Son extends Component {
        static contextType = ThemeContext;
        render(){
            return (
                <> <p style={{color:this.context.color}}>{this.context.name}</p> <button onClick={()=>{this.context.setColor('red')}}> Change Color To Red </button> <button onClick={()=>{this.context.setColor('green')}}> Change Color To Green </button> </> ) } } 复制代码

函数组件

  • Context三步曲
    • 【1】全局经过React.createContext()建立ThemeContext对象
    import React, {Component} from 'react';
    const ThemeContext = React.createContext();
    复制代码
    • 【2】父组件经过ThemeContext.Provider组件包裹,并在此组件的value属性上定义上下文对象
    class Father extends Component {
        constructor(props){
            super(props);
            this.state = {
                name:'GuYan',
                color:'red'
            }
        }
        render(){
            const contextValue = {
                name:this.state.name,
                color:this.state.color
            }
            return (
                <ThemeContext.Provider value = {contextValue}> <Son/> </ThemeContext.Provider> ) } setColor = (color) =>{ this.setColor({ color:color }) } } 复制代码
    • 【3】子组件经过ThemeContext.Consumer组件包裹,须要注意的是这里须要在内部包裹一个匿名函数组件的形式
    function Son(){
        return (
            <ThemeContext.Consumer> { value=>( <> <p style={{color:value.color}}>{value.name}</p> <button onClick={()=>{value.setColor('red')}}>Change Color To Red</button> <button onClick={()=>{value.setColor('green')}}>Change Color To Green</button> <GrandSon/> </> ) } </ThemeContext.Consumer> ) } 复制代码
    function GrandSon(){
        return (
            <ThemeContext.Consumer> { value=>( <p style={{color:value.color}}>name:{value.name}</p> ) } </ThemeContext.Consumer> ) } 复制代码

原理

  • 控制台输出ThemeContext对象,结果以下
  • 由上图咱们能够看出ThemeContext对象中比较重要的三个属性,也就是说React.createContext()执行返回比较重要的三个属性
    • 【1】$$typeof
    • 【2】Provider
    • 【3】Consumer
  • 源码实现
import React,{Component} from 'react';
function myCreateContext(){
    const $$typeof = Symbol.for('react.context');
    class Provider extends Component{
        static value;
        static $$typeof = Symbol.for('react.provider');
        constructor(props){
            super(props);
            Provider.value = props.value;
            this.state = {
                value:props.value;
            }
        }
        static getDerivedStateFromProps(nextProps,prevState){
            Provider.value = nextProps.value;
            return {value:nextProps.value};
        }
        render(){
            return this.props.children;
        }
    }
    class Consumer extends Component{
        static $$typeof = Symbol.for('react.consumer');
        render(){
            return this.props.children(Provider.value);
        }
    }
    return {
        $$typeof,
        Provider,
        Consumer
    }
}
复制代码
相关文章
相关标签/搜索