React+DvaJs 之 Context与Props

Context

React 遵循 Flux 思想进行数据流传递的时候,常见的方式是通过props 逐层从父级向子组件传递。

context 是实验功能,可以简化传递过程,尤其是组件树层数很多的时候,但是不容易发现传递的流向,所以谨慎使用

传统的props传值

class Button extends React.Component {
  render() {
    return (
      
    );
  }
}

class Message extends React.Component {
  render() {
    return (
      <div>
        {this.props.text} 
      div>
    );
  }
}

class MessageList extends React.Component {
  render() {
    const color = "purple";
    const children = this.props.messages.map((message) =>
      
    );
    return <div>{children}div>;
  }
}

这个例子中,就是从Message 组件传递button组件的 color属性来实现主题控制,整个传递过程有些繁琐,如果使用context,代码如下:

class Button extends React.Component {
  render() {
    return (
      
    );
  }
}

Button.contextTypes = {
  color: React.PropTypes.string
};

class Message extends React.Component {
  render() {
    return (
      <div>
        {this.props.text} 
      div>
    );
  }
}

class MessageList extends React.Component {
  getChildContext() {
    return {color: "purple"};
  }

  render() {
    const children = this.props.messages.map((message) =>
      
    );
    return <div>{children}div>;
  }
}

MessageList.childContextTypes = {
  color: React.PropTypes.string
};

通过给MessageList 添加childContextTypesgetChildContext,可以自动在组件树的运行上下文环境中传递值,作为父级设置值的时候,父级组件只能以类的形式声明,无状态函数式声明不可以。
子组件随后就可以使用context获取,但是必须定义 contextTypes,负责获取的是空对象。组件的声明就没有父组件的限制,可以是无状态函数式(stateless functional),或类。

各组件生命周期方法中的context

如果contextTypes在组件内部定义的话,下面生命周期函数将额外多一个参数(context对象)

void componentWillReceiveProps(
  object nextProps, object nextContext
)

boolean shouldComponentUpdate(
  object nextProps, object nextState, object nextContext
)

void componentWillUpdate(
  object nextProps, object nextState, object nextContext
)

void componentDidUpdate(
  object prevProps, object prevState, object prevContext
)

无状态函数式组件使用 context样例:

const Button = ({children}, context) =>
  <button style={{background: context.color}}>
    {children}
  button>;

Button.contextTypes = {color: React.PropTypes.string};

更新context

stateprops改变时会自动调用getChildContext,为了更新context中的数据,可以使用this.setState来触发局部state更新,这种更新会传递到所有子节点。

class MediaQuery extends React.Component {
  constructor(props) {
    super(props);
    this.state = {type:'desktop'};
  }

  getChildContext() {
    return {type: this.state.type};
  }

  componentDidMount() {
    const checkMediaQuery = () => {
      const type = window.matchMedia("(min-width: 1025px)").matches ? 'desktop' : 'mobile';
      if (type !== this.state.type) {
        this.setState({type});
      }
    };

    window.addEventListener('resize', checkMediaQuery);
    checkMediaQuery();
  }

  render() {
    return this.props.children;
  }
}

MediaQuery.childContextTypes = {
  type: React.PropTypes.string
};

如果没看懂或者有任何,可以看看facebook 原版文章,欢迎留言交流

你可能感兴趣的:(react,react,context,props,dvajs)