props
当 React 元素为用户自定义组件时,它会将 JSX 所接收的属性(attributes)转换为单个对象传递给组件,这个对象被称之为 “props”。

function Welcome(props) {  return <h1>Hello, {props.name}</h1>;}const element = <Welcome name="Sara" />;ReactDOM.render(  element,  document.getElementById('root'));

React 调用 Welcome 组件,并将 {name: 'Sara'} 作为 props 传入。
注意:组件无论是使用函数声明还是通过 class 声明,都决不能修改自身的 props。

context
在一个典型的 React 应用中,数据是通过 props 属性自上而下(由父及子)进行传递的。但是如果有些属性是应用程序中许多组件都需要的,此时我们希望可以共享这些值,于是Context就出现了。
Context 提供了一种在组件之间共享此类值的方式,而不必显式地通过组件树的逐层传递 props。
Context就像我们在应用中使用全局变量一样。我们应当谨慎使用Context。

var Button = React.createClass({  contextTypes: {    color: React.PropTypes.string  },  render: function() {    return (      <button style={{background: this.context.color}}>        {this.props.children}      </button>    );  }});var Message = React.createClass({  render: function() {    return (      <div>        {this.props.text} <Button>Delete</Button>      </div>    );  }});var MessageList = React.createClass({  childContextTypes: {    color: React.PropTypes.string  },  getChildContext: function() {    return {color: "purple"};  },  render: function() {    return (    <div>        <Message text='警告'/>    </div>    );  }});

在这个例子中,我们想在MessageList 组件中,传递color值到子组件Message的子组件Button中(即越级传值),需要以下步骤。

首先,我们需要在MessageList组件中定义 childContextTypes 和 getChildContext。
其次,我们需要在Button组件中定义contextTypes。
这样我们就可以在Button组件中使用这些值了。

备注:React 能够自动地把信息(数据)向所有设置了 contextTypes 的子树进行传递。如果 contextTypes 在子组件中还没有定义,那 this.context将会是一个空对象。

那我们应该怎么更新组件的 Context 呢?
答案是,把 Context 和组件的 State关联起来,当组件的state或者props改变的时候,getChildContext函数会自动调用,更新Context 并把这个新的Context和其他改变一起传输到子树。

var MediaQuery = React.createClass({  getInitialState: function(){    return {type:'desktop'};  },  childContextTypes: {    type: React.PropTypes.string  },  getChildContext: function() {    return {type: this.state.type};  },  componentDidMount: function(){    var checkMediaQuery = function(){      var type = window.matchMedia("(min-width: 1025px)").matches ? 'desktop' : 'mobile';      if (type !== this.state.type){        this.setState({type:type});       }    };    window.addEventListener('resize', checkMediaQuery);    checkMediaQuery();  },  render: function(){    return this.props.children;  }});

其实在大多数情况下,为了代码的清晰可观,我们都应该尽可能避免使用Context(就像全局变量一样)。Context的最佳应用情景应该是像用户登录、应用语言或者是应用主题的这一类情景,这些都是真实的全局变量。