React 复合组件
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了React 复合组件相关的知识,希望对你有一定的参考价值。
var Avatar = React.createClass({ render: function() { return ( <div> <ProfilePic username={this.props.username} /> <ProfileLink username={this.props.username} /> </div> ); } }); var ProfilePic = React.createClass({ render: function() { return ( <img src={‘http://graph.facebook.com/‘ + this.props.username + ‘/picture‘} /> ); } }); var ProfileLink = React.createClass({ render: function() { return ( <a href={‘http://www.facebook.com/‘ + this.props.username}> {this.props.username} </a> ); } }); React.render( <Avatar username="pwh" />, document.getElementById(‘example‘) );
从属关系
- 上面例子中,
Avatar
拥有ProfilePic
和ProfileLink
的实例 ,拥有者
就是给其它组件设置props
的那个组件 - 正式地说, 如果组件
Y
在render()
方法是创建了组件X
,那么Y
就拥有X
- 组件不能修改自身的
props
- 它们总是与它们拥有者设置的保持一致。这是保持用户界面一致性的关键性原则 - 把从属关系与父子关系加以区别至关重要。从属关系是 React 特有的,而父子关系简单来讲就是 DOM 里的标签的关系
- 例子中,
Avatar
拥有div
、ProfilePic
和ProfileLink
实例,div
是ProfilePic
和ProfileLink
实例的父级(但不是拥有者)
子级
实例化 React 组件时,你可以在开始标签和结束标签之间引用在 React 组件或者 javascript 表达式:
<Parent><Child /></Parent>
Parent
能通过专门的 this.props.children
props 读取子级。
动态子级
如果子组件位置会改变(如在搜索结果中)或者有新组件添加到列表开头(如在流中)情况会变得更加复杂。如果子级要在多个渲染阶段保持自己的特征和状态,在这种情况下,你可以通过给子级设置惟一标识的 key 来区分
render: function() { var results = this.props.results; return ( <ol> {results.map(function(result) { return <li key={result.id}>{result.text}</li>; })} </ol> ); }
当 React 校正带有 key 的子级时,它会确保它们被重新排序(而不是破坏)或者删除(而不是重用)。 务必
把 key
添加到子级数组里组件本身上,而不是每个子级内部最外层 html 上:
/ 错误! var ListItemWrapper = React.createClass({ render: function() { return <li key={this.props.data.id}>{this.props.data.text}</li>; } }); var MyComponent = React.createClass({ render: function() { return ( <ul> {this.props.results.map(function(result) { return <ListItemWrapper data={result}/>; })} </ul> ); } }); // 正确 :) var ListItemWrapper = React.createClass({ render: function() { return <li>{this.props.data.text}</li>; } }); var MyComponent = React.createClass({ render: function() { return ( <ul> {this.props.results.map(function(result) { return <ListItemWrapper key={result.id} data={result}/>; })} </ul> ); } });
- 也可以传递 object 来做有 key 的子级。object 的 key 会被当作每个组件的
key
。 - 要牢记 JavaScript 并不总是保证属性的顺序会被保留。实际情况下浏览器一般会保留属性的顺序,除了 使用 32 位无符号数字做为 key 的属性。
- 数字型属性会按大小排序并且排在其它属性前面。
- React 渲染组件的顺序就是混乱。可以在 key 前面加一个字符串前缀来避免:
render: function() { var items = {}; this.props.results.forEach(function(result) { // 如果 result.id 看起来是一个数字(比如短哈希),那么对象字面量的顺序就得不到保证。这种情况下,需要添加前缀,来确保 key 是字符串。 items[‘result-‘ + result.id] = <li>{result.text}</li>; }); return ( <ol> {items} </ol> ); }
以上是关于React 复合组件的主要内容,如果未能解决你的问题,请参考以下文章
元素类型无效:需要一个字符串(对于内置组件)或一个类/函数(对于复合组件)但得到:未定义的 React
React.jsx:类型无效 - 需要一个字符串(对于内置组件)或一个类/函数(对于复合组件)但得到:未定义