Webpack + React 开发 03 props
React中组件的用法与原生的 HTML 标签完全一致,可以任意加入属性,比如 <HelloWorld name="John"> ,就是 HelloWorld 组件加入一个 name 属性,值为 John。和直接使用 <div name="John"> 不同,React组件被渲染出来之后,在渲染之后的dom节点中是不能直接看得到 name 属性的,怎么获取呢?组件的属性可以在组件类的 this.props 对象上获取,比如 name 属性就可以通过 this.props.name 读取。
添加组件属性,有一个地方需要注意,就是 class 属性需要写成 className ,for 属性需要写成 htmlFor ,这是因为 class 和 for 是 JavaScript 的保留字。
this.props.children
this.props 对象的属性与组件的属性一一对应,但是有一个例外,就是 this.props.children 属性。它表示组件的所有子节点;
var NotesList = React.createClass({ render: function() { return ( <ol> { React.Children.map(this.props.children, function (child) { return <li>{child}</li>; }) } </ol> ); } }); render( <NotesList> <span>hello</span> <span>world</span> </NotesList>, document.getElementById('testDiv') );
渲染之后的dom节点内容如下:
<ol data-reactroot=""> <li><span>hello</span></li> <li><span>world</span></li> </ol>
其中NodeList还可以改写成:
var NotesList = React.createClass({ render: function() { return ( <ol> { (this.props.children).map((child, index) => { return <li key={index}>{child}</li>; }) } </ol> ); } });
需要注意的是这样写最好给li标签添加一个key属性,react建议这样做。
This is a suggestions of reactjs to improve the rendering performance. By providing a unique key for each dynamically created element,
it is possibile to minimize possible DOM changes.
如果没添加key,则会报如下的警告信息:
Each child in an array or iterator should have a unique "key" prop.
参考自 stackoverflow
上面代码的 NoteList 组件有两个 span 子节点,它们都可以通过 this.props.children 读取;
这里需要注意, this.props.children 的值有三种可能:如果当前组件没有子节点,它就是 undefined ;如果有一个子节点,数据类型是 object ;如果有多个子节点,数据类型就是 array 。所以,处理 this.props.children 的时候要小心。
React 提供一个工具方法 React.Children 来处理 this.props.children 。我们可以用 React.Children.map 来遍历子节点,而不用担心 this.props.children 的数据类型是 undefined 还是 object。更多的 React.Children 的方法,请参考官方文档。
Protypes
组件的属性可以接受任意值,字符串、对象、函数等等都可以。有时,我们需要一种机制,验证别人使用组件时,提供的参数是否符合要求。组件类的PropTypes属性,就是用来验证组件实例的属性是否符合要求
class MyTitle extends React.Component { propTypes() { return { title: React.PropTypes.string.isRequired }; } render() { return (<div> {this.props.title} </div>); } }
也可以使用 createClass 的方式,和上面有一点区别;
var MyTitle = React.createClass({ propTypes: { title: React.PropTypes.string.isRequired, }, render: function() { return <h1> {this.props.title} </h1>; } });
Mytitle组件有一个title属性。PropTypes 告诉 React,这个 title 属性是必须的,而且它的值必须是字符串,如果设置成其它类型值,则会出错。
此外,getDefaultProps
方法可以用来设置组件属性的默认值。
var MyTitle = React.createClass({ getDefaultProps : function () { return { title : 'Hello World' }; }, render: function() { return <h1> {this.props.title} </h1>; } });
...this.props
组件的 props 是设置到具体组件上的属性 <ComponentA name='ccf'>IM</ComponentA>,像是这样的一个组件,就有一个name属性和一个children属性,其中children为字符串 'IM';
在定义组件的时候可以通过...this.props
var Inner = React.createClass({ render: function() { return <div {...this.props}></div> } }); // ... <Inner age="22">ABCDE</Inner> //
更多 propTypes 参考官方文档。