JSX赋予了React组件强大的表现能力,它允许我们使用类似HTML的语法来创建自定义元素和组件。结合小巧、简单的组件和数据对象,可以构造出庞大而复杂的组件,这就是组件复合。
1. 组件的组合与从属关系
1.1 组件的组合
我们要实现一个显示用户头像和用户名的组件,其结构如下:
<div> <img src="……" /> <a href="……">userName</a> </div>
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://niefengjun.cn/' + this.props.username + '/picture'} />
);
}
});
var ProfileLink = React.createClass({
render: function() {
return (
<a href={'http://niefengjun.cn/' + this.props.username}>
{this.props.username}
</a>
);
}
});
ReactDOM.render(
<Avatar username="nodejs" />,
document.getElementById('example')
);
1.2 组件从属关系
在上面示例中,Avatar组件是ProfilePic和ProfileLink实例的拥有者(即:在render()中创建了所拥有的组件)。
React组件从属关系不同于父子关系,从属关系是React组件所特有的,父子组件类似于DOM中的元素关系。如:Avatar组件拥有div、ProfilePic和ProfileLink实例,而div是ProfilePic和ProfileLink的父级,但不是拥有者。
2. 组件的子级
2.1 子级
我们可以实例化 React 组件时添加子级,添加子级可以在开始标签和结束标签之间引用 React 组件或 Javascript 表达式引用,其语法结构如下:
<Parent><Child /></Parent>
在父组件中,可以通过this.props.children属性读取子组件,子组件是一个通过React.Children工具类来操作的,不透明的数据结构。
2.2 动态子级
有些时候组件子级数量是不确定的,因此我们需要跟据父组件数据来动态生成子级,生成子级时一般需要向子级传递数据。
如,动态生成一个如下结构的网站菜单:
<ul> <li><a href="http://www.niefengjun.cn/nodejs">Node.js</a></li> <li><a href="http://www.niefengjun.cn/javascript">JavaScript</a></li> …… </ul>
实现如下:
var ListItemWrapper = React.createClass({
render: function() {
return <li><a href="{this.props.data.url}">{this.props.data.text}</a></li>;
}
});
var Menu = React.createClass({
render: function() {
return (
<ul>
{this.props.menus.map(function(result) {
return <ListItemWrapper key={result.id} data={result} />;
})}
</ul>
);
}
});
var menus = [{id: 1, url:'http://niefengjun.cn/nodejs', text:'Node.js'},
{id: 2, url:'http://niefengjun.cn/javascript', text:'JavaScript'},
{id: 3, url:'http://niefengjun.cn/db', text:'数据库'}
]
ReactDOM.render(
<Menu menus={menus} />,
document.getElementById('example')
);
