在 React 中,数据的流向是单向的 —- 从父节点传递到子节点。如果顶层组件的某个 props 改变了,React 会递归地向下遍历整颗组件树,重新渲染所有使用这个属性的组件。
React 组件内部还有自己的状态,这些状态只能在组件内部修改。你可以把 React 组件类比成一个函数,它接受 props 和 state 作为参数,然后返回一个虚拟的 DOM 表现。
Props 用过 props 你可以把任意类型的数据传递给组件。
在 JSX 中,你可以他 props 设置为字符串:
<a href="/surveys/add">Add survey</a> 也可以使用 {} 花括号语法来注入 JavaScript 传递任意类型的变量:
<a href={'/surveys' + survey.id}>{survey.title}</a> 还可以使用 JSX 的展开语法把 props 设置成一个对象:
var ListSurvey = React.createClass({ render: function() { var props = { one: 'foo', two: 'bar' }; return <SurveyTable {...props} />; } }); props 还可以用来添加事件处理器:
var SaveButton = React.createClass({ render: function() { return ( <a className="button save" onClick={this.handleClick}>Save</a> ); }, handleClick: function() { // ... } }); 如上,我们给链接标签传递了一个 onClick 属性,值为 handleClick 函数,当用户点击链接的时候, handleClick 方法将被调用。
PropTypes 通过在组件中定义一个配置对象,React 提供了一种验证 props 的方式:
var SurveyTableRow = React.createClass({ propTypes: { survey: React.PropTypes.shape({ id: React.PropTypes.number.isRequired }).isRequired, onClick: React.PropTypes.func } }); 给 props 配置验证对象后,当组件初始化的时候,如果传递给 props 的值和 propTypes 不匹配,则会打印一个 console.warn() 日志,如果是可选的配置,可以去掉 .isRequired 。
在应用中使用 propTypes 并不是强制性的,但是这提供了一种很好的方式来描述组件的 API.
getDefaultProps() 可以为组件添加 getDefaultProps() 函数来设置属性的默认值,不过这应该只针对那些 非必须 的属性。
var SurveyTable = React.createClass({ getDefaultProps: function() { return { survey: [], // ... }; } }); getDefaultProps() 并不是组件实例化时被调用的,而是在 React.createClass() 调用时就被调用了,返回值会被缓存起来。也就是说,不能通过 getDefaultProps() 中使用任何特定的实例数据。
State 每一个 React 组件都可以拥有自己的 state , state 与 props 的区别在于前者只存在于组件的内部。
state 可以用来确定一个元素的视图状态。以 <Dropdown/> 组件为例:
var CountryDropdown = React.createClass({ getInitialState: function() { return { showOptions: false }; }, render: function() { var options; if(this.state.showOptions) { options = ( <ul className="options"> <li>United States of America</li> <li>New Zealand</li> <li>Denmark</li> </ul> ); } return ( <div className="dropdown" onClick={this.handleClick}> <label>Choose a country</label> </div> ); }, handleClick: function() { this.setState({ showOptions: true }); } }); 在上例中, state 被用来记录是否在下拉框中显示可选项。
state 可以用过 setState 来修改,也可以使用上面出现的 getInitialState() 方法提供一组默认的值。只要 setState 被调用, render() 就会被调用。如果 render() 函数返回有变化,虚拟 DOM 就会更新,真是的 DOM 也会被更新,最终用户就会在浏览器中看到变化。
state 还是 props 不要在 state 中保存计算出的值,而应该保存最简单的数据。比如前面出现的勾选状态,如果没有它就无法勾选复选框;比如用来表示下拉选项是否显示布尔值,又比如输入框等等。