React Context使用

设计目的是为了共享那些对于一个组件树而言的全局数据,比如当前认证用户,主题,首选语言等。context主要运用场景在于很多不同层级的组件需要访问同一些数据,需要谨慎使用,因为会使复用性变差

如果只是想避免层层传递一些属性,组件组合有时候是比context更好的解决方案

context使用条件

  • 上级组件需要声明自己支持的context
  • 子组件要声明自己需要使用的context

context使用注意点

  • 父组件需要声明自己支持 context,并提供 context 中属性的 PropTypes

  • 子组件需要声明自己需要使用 context,并提供其需要使用的 context 属性的 PropTypes

  • 父组件需提供一个 getChildContext 函数,以返回一个初始的 context 对象

  • 如果组件中使用构造函数(constructor),还需要在构造函数中传入第二个参数 context,并在 super 调用父类构造函数是传入 context,否则会造成组件中无法使用 context

    constructor(props,context){
      super(props,context);
    }
    
  • 改变 context 对象

    我们不应该也不能直接改变 context 对象中的属性,要想改变 context 对象,只有让其和父组件的 state 或者 props 进行关联,在父组件的 state 或 props 变化时,会自动调用 getChildContext 方法,返回新的 context 对象,而后子组件进行相应的渲染。修改 App.js,让 context 对象可变

context使用方法

/*app.js------------------------------------------------------------*/
import React, { Component } from 'react';
import PropTypes from "prop-types";
import Sub from "./Sub";
export default class App extends Component{
    // 父组件声明自己支持 context
    static childContextTypes = {
        color:PropTypes.string,
        callback:PropTypes.func,
    }

    // 父组件提供一个函数,用来返回相应的 context 对象
    getChildContext(){
        return{
            color:this.state.color,
            callback:this.callback.bind(this)
        }
    }

    callback(msg){
        console.log(msg)
    }

    render(){
        return(
            <div>
                <Sub></Sub>
            </div>
        );
    }
} 
/*Father.js --------------------------------------------*/

import React, { Component } from 'react';
import PropTypes from "prop-types";
import Son from "../Son/index";
class Father extends Component {
    constructor(props){
        super(props)
    }
    static contextTypes = {
        color:PropTypes.string,
        callback:PropTypes.func,
    }
    render() {
        return (
            <div>
            <Son />
        </div>
        );
    }
}
export default Father;


/*无状态组件--------------------------------------------------------*/


const SubSub = (props,context) => {
    const style = { color:context.color }
    const cb = (msg) => {
        return () => {
            context.callback(msg);
        }
    }

    return(
        <div style = { style }>
            SUBSUB
            <button onClick = { cb("我胡汉三又回来了!") }>点击我</button>
        </div>
    );
}

SubSub.contextTypes = {
    color:PropTypes.string,
    callback:PropTypes.func,
}
/*Son.js-----------------------------------------------------------*/
import React,{ Component } from "react";
import PropTypes from "prop-types";

export default class Son extends Component{
    // 子组件声明自己需要使用 context
    static contextTypes = {
        color:PropTypes.string,
        callback:PropTypes.func,
    }
    render(){
        const style = { color:this.context.color }
        const cb = (msg) => {
            return () => {
                this.context.callback(msg);
            }
        }
        return(
            <div style = { style }>
                SUBSUB
                <button onClick = { cb("我胡汉三又回来了!") }>点击我</button>
            </div>
        );
    }
}
posted @ 2020-11-02 15:32  Yanzq-X  阅读(166)  评论(0)    收藏  举报