React 新context api

一:旧Context API

// 传递者,生成数据并放入context中
class DeliverComponent extends Component {  
  getChildContext() {    
      return { color: "purple" };
  }
  render() {    
    return <MidComponent />
  }
}
DeliverComponent.childContextTypes = {  
  color: PropTypes.string
};
// 中间与context无关的组件
const MidComponent = (props) => <ReceiverComponent />;// 接收者,需要用到context中的数据
const ReceiverComponent = (props, context) =>  
  <div style={{ color: context.color }}> Hello, this is receiver. </div>;
ReceiverComponent.contextTypes = {  
  color: PropTypes.string
};
ReactDOM.render(  
  <DeliverComponent>
    <MidComponent>
      <ReceiverComponent />
    </MidComponent>
  </DeliverComponent>, document.getElementById('root'));

可以看到,使用context api可以把DeliverComponent中的参数color直接跨越MidComponent传递到ReceiverComponent中,不需要冗余的使用props参数传递,特别是ReceiverComponent层级特别深的时候,使用context api能够很大程度上节省重复代码避免bug。

旧Context API的缺陷

 1.代码冗余:提供context的组件要定义`childContextTypes`与`getChildContext`才能把context传下去。同时接收context的也要先定义contextTypes才能正确拿到数据。

2.传递效率:虽然功能上context可以跨层级传递,但是本质上context也是同props一样一层一层的往下传递的,当层级过深的时候还是会出现效率问题。

3.shouldComponentUpdate:由于context的传递也是一层一层传递,因此它也会受到shouldComponent的阻断。换句话说,当传递组件的context变化时,如果其下面某一个中间组件的shouldComponentUpdate方法返回false,那么之后的接收组件将不会收到任何context变化。

 二、新Context API

React自16.3开始提供了一个新的context api, 新的context api可以直接将context数据传递到传递到子组件中而不需要像旧context api那样级联传递

import React, { Component, createContext } from 'react';
const DEFAULT_STATE = {color: 'red'};  
const { Provider, Consumer } = createContext(DEFAULT_STATE);// 传递者,生成数据并放context中
class DeliverComponent extends Component {  
  state = { color: "purple" };

  render() {
     return (    
  <Provider value={this.state}>
        <MidComponent />
      </Provider>
    )
  }
}
// 中间与context无关的组件
const MidComponent = (props) => <ReceiverComponent />;

// 接收者,需要用到context中的数据
const ReceiverComponent = (props) => (  
  <Consumer>
    {context => (
      <div style={{ color: context.color }}> Hello, this is receiver. </div>
    )}
  </Consumer>
);

ReactDOM.render(  
  <DeliverComponent>
    <MidComponent>
      <ReceiverComponent />
    </MidComponent>
  </DeliverComponent>, document.getElementById('root'));

可以看到新的context api主要包含一个Provider和Consumer对,在Provider输入的数据可以在Consumer中获得。 新context api的要点如下:

1. Provider和 Consumer必须来自同一次 React.createContext调用。也就是说 NameContext.Provider和 AgeContext.Consumer是无法搭配使用的。

2. React.createContext方法接收一个默认值作为参数。当 Consumer外层没有对应的 Provider时就会使用该默认值。

3. Provider 组件的 value prop 值发生变更时,其内部组件树中对应的 Consumer组件会接收到新值并重新执行 children函数。此过程不受 shouldComponentUpdete 方法的影响。

4. Provider组件利用 Object.is 检测 value prop 的值是否有更新。注意 Object.is和 === 的行为不完全相同。

5. Consumer组件接收一个函数作为 children prop 并利用该函数的返回值生成组件树的模式被称为 Render Props 模式。

猜你喜欢

转载自blog.csdn.net/cao_dan/article/details/83616286