zoukankan      html  css  js  c++  java
  • React context基本用法

    React context基本用法

     

    React的context就是一个全局变量,可以从根组件跨级别在React的组件中传递。React context的API有两个版本,React16.x之前的是
    老版本的context,之后的是新版本的context。

    1.老版本的context

    getChildContext 根组件中声明,一个函数,返回一个对象,就是context
    childContextTypes 根组件中声明,指定context的结构类型,如不指定,会产生错误
    contextTypes 子孙组件中声明,指定要接收的context的结构类型,可以只是context的一部分结构。contextTypes 没有定义,context将是一个空对象。
    this.context 在子孙组件中通过此来获取上下文
    (注:从React v15.5开始 ,React.PropTypes 助手函数已被弃用,可使用 prop-types 库 来定义contextTypes)

    举例如下:

    复制代码
    //根组件
    class MessageList extends React.Component {
      getChildContext() {
        return {color: "purple",text: "item text"};
      }
    
      render() {
        const children = this.props.messages.map((message) =>
          <Message text={message.text} />
        );
        return <div>{children}</div>;
      }
    }
    
    MessageList.childContextTypes = {
      color: React.PropTypes.string
      text: React.PropTypes.string
    };
    
    //中间组件
    class Message extends React.Component {
      render() {
        return (
          <div>
            <MessageItem />
            <Button>Delete</Button>
          </div>
        );
      }
    }
    
    //孙组件(接收组件)
    class MessageItem extends React.Component {
      render() {
        return (
          <div>
            {this.props.text}
          </div>
        );
      }
    }
    
    MessageItem.contextTypes = {
      text: React.PropTypes.string
    };
    
    class Button extends React.Component {
      render() {
        return (
          <button style={{background: this.context.color}}>
            {this.props.children}
          </button>
        );
      }
    }
    
    Button.contextTypes = {
      color: React.PropTypes.string
    };
    复制代码

    2.新版本的context

    新版本的React context使用了Provider和Customer模式,和redux-react的模式非常像。在顶层的Provider中传入value,
    在子孙级的Consumer中获取该值,并且能够传递函数,用来修改context,如下代码所示:

    复制代码
    //创建Context组件
    const ThemeContext = React.createContext({
      theme: 'dark',
      toggle: () => {}, //向上下文设定一个回调方法
    });
    
    //运行APP
    class App extends React.Component {
      constructor(props) {
        super(props);
    
        this.toggle = () => { //设定toggle方法,会作为context参数传递
          this.setState(state => ({
            theme:
              state.theme === themes.dark
                ? themes.light
                : themes.dark,
          }));
        };
    
        this.state = {
          theme: themes.light,
          toggle: this.toggle,
        };
      }
    
      render() {
        return (
          <ThemeContext.Provider value={this.state}> //state包含了toggle方法
            <Content />
          </ThemeContext.Provider>
        );
      }
    }
    
    //中间组件
    function Content() {
      return (
        <div>
          <Button />
        </div>
      );
    }
    
    //接收组件
    function Button() {
      return (
        <ThemeContext.Consumer>
          {({theme, toggle}) => (
            <button
              onClick={toggle} //调用回调
              style={{backgroundColor: theme}}>
              Toggle Theme
            </button>
          )}
        </ThemeContext.Consumer>
      );
    }
    复制代码

    详细用法可以参考官方文档:https://react.docschina.org/docs/context.html#reactcreatecontext

    3. context在如下的生命周期钩子中可以使用

    constructor(props, context)
    componentWillReceiveProps(nextProps, nextContext)
    shouldComponentUpdate(nextProps, nextState, nextContext)
    componentWillUpdate(nextProps, nextState, nextContext)
    componentDidUpdate(prevProps, prevState, prevContext)

    4. 在无状态组件中可以通过参数传入

    复制代码
    function D(props, context) {
      return (
        <div>{this.context.user.name}</div>
      );
    }
    
    D.contextTypes = {
      user: React.PropTypes.object.isRequired
    }
    复制代码

    5. React context的局限性

    1. 在组件树中,如果中间某一个组件 ShouldComponentUpdate returning false 了,会阻碍 context 的正常传值,导致子组件无法获取更新。
    2. 组件本身 extends React.PureComponent 也会阻碍 context 的更新。

    注意点:

    1. Context 应该是唯一不可变的
    2. 组件只在初始化的时候去获取 Context

    参考:https://www.tuicool.com/articles/nUryimf
         https://segmentfault.com/a/1190000012575622

  • 相关阅读:
    年轻程序员不讲武德,做表竟然拖拉拽
    如何做好一个领导者?
    创业相关的书籍推荐
    有关创新思维的书籍推荐
    如何做好公司企业文化建设?
    组织变革的类型
    怎样进行自我管理?这些书告诉你答案
    PHP分页算法
    Knockoutjs 实现省市联动
    MySQL InnoDB存储引擎外键约束
  • 原文地址:https://www.cnblogs.com/jkr666666/p/10572143.html
Copyright © 2011-2022 走看看