當咱們在設計接口的時候,將一些常見的設計元素(如按鈕、表單、佈局等)拆分紅有着良好接口的可重用的組件。這樣的話,下次你構建UI的時候只要寫少許的代碼。html
隨着應用的增加,確保你的組件正確使用是有必要的。React容許咱們指定propTypes。React.PropTypes聲明瞭一系列的校驗確保咱們接收的數據是合法的。若是不合法的數據出如今屬性當中,控制檯會打印警告信息。下面是不一樣的校驗類型:node
React.createClass({ propTypes: { // You can declare that a prop is a specific JS primitive. By default, these // are all optional. optionalArray: React.PropTypes.array, optionalBool: React.PropTypes.bool, optionalFunc: React.PropTypes.func, optionalNumber: React.PropTypes.number, optionalObject: React.PropTypes.object, optionalString: React.PropTypes.string, // Anything that can be rendered: numbers, strings, elements or an array // containing these types. optionalNode: React.PropTypes.node, // A React element. optionalElement: React.PropTypes.element, // You can also declare that a prop is an instance of a class. This uses // JS's instanceof operator. optionalMessage: React.PropTypes.instanceOf(Message), // You can ensure that your prop is limited to specific values by treating // it as an enum. optionalEnum: React.PropTypes.oneOf(['News', 'Photos']), // An object that could be one of many types optionalUnion: React.PropTypes.oneOfType([ React.PropTypes.string, React.PropTypes.number, React.PropTypes.instanceOf(Message) ]), // An array of a certain type optionalArrayOf: React.PropTypes.arrayOf(React.PropTypes.number), // An object with property values of a certain type optionalObjectOf: React.PropTypes.objectOf(React.PropTypes.number), // An object taking on a particular shape optionalObjectWithShape: React.PropTypes.shape({ color: React.PropTypes.string, fontSize: React.PropTypes.number }), // You can chain any of the above with `isRequired` to make sure a warning // is shown if the prop isn't provided. requiredFunc: React.PropTypes.func.isRequired, // A value of any data type requiredAny: React.PropTypes.any.isRequired, // You can also specify a custom validator. It should return an Error // object if the validation fails. Don't `console.warn` or throw, as this // won't work inside `oneOfType`. customProp: function(props, propName, componentName) { if (!/matchme/.test(props[propName])) { return new Error('Validation failed!'); } } }, /* ... */ });
React容許咱們下面的方式自定義屬性的默認值:緩存
var ComponentWithDefaultProps = React.createClass({ getDefaultProps: function() { return { value: 'default value' }; } /* ... */ });
getDefaultProps()的值將會被緩存,當this.props.value的值沒有被父組件指定時,將會使用這個默認值。app
經過屬性延伸的語法,能夠快速的將組件屬性添加到HTML標籤上:ide
var CheckLink = React.createClass({ render: function() { // This takes any props passed to CheckLink and copies them to <a> return <a {...this.props}></a>; } }); React.render( <CheckLink href="/checked.html"> Click here! </CheckLink>, document.getElementById('example') );
須要注意的是,這種寫法會添加全部的屬性。當標籤內容爲空時,children也會被添加其中。上面的例子是一個很好的實踐。佈局
在React當中,組件複用可以減小咱們的代碼量。但有時候不一樣的組件之間可能會相同的功能點。這個一般被叫作Cross-cutting concern。React提供了混入來解決這個問題。
官方舉例說明的一種狀況:一個組件,每隔一段時間更新一次。很容易就想到使用setInterval(),當不須要的時候須要取消Interval。React提供了組件生命週期的方法告訴咱們組件何時被建立和銷燬。根據這些建立一個簡單的混入:ui
var SetIntervalMixin = { componentWillMount: function() { this.intervals = []; }, setInterval: function() { this.intervals.push(setInterval.apply(null, arguments)); }, componentWillUnmount: function() { this.intervals.map(clearInterval); } }; var TickTock = React.createClass({ mixins: [SetIntervalMixin], // Use the mixin getInitialState: function() { return {seconds: 0}; }, componentDidMount: function() { this.setInterval(this.tick, 1000); // Call a method on the mixin }, tick: function() { this.setState({seconds: this.state.seconds + 1}); }, render: function() { return ( <p> React has been running for {this.state.seconds} seconds. </p> ); } }); React.render( <TickTock />, document.getElementById('example') );