在 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
中保存计算出的值,而应该保存最简单的数据。比如前面出现的勾选状态,如果没有它就无法勾选复选框;比如用来表示下拉选项是否显示布尔值,又比如输入框等等。