React推荐将每一个业务点都建立一个独立的组件,并将所有逻辑和标签封装在其中,创建组件使用React.createClass()方法。JSX以干净简洁的方式保证了组件中的标签与所有业务逻辑的分离,它不仅提供了清晰、直观的方式来描述组件树,同时也让应用程序更加符合逻辑。
1. 定义一个组件
现在,我们要定义一个分页组件,期望输出如下HTML:
<div className="divider"> <h2>Questions</h2><hr/> </div>
要创建一个上面HTML为内容的React组件,我们使用createClass()进行包装,并使用render方法渲染到页面:
var App = React.createClass({
render: function () {
return (
<div className="divider">
<h2>Questions</h2><hr/>
</div>
)
}
});
ReactDOM.render(
React.createElement(App),
document.getElementById('example')
);
组件制作完成,现在已经可以渲染到页面上了。但只能静态显示,为了让其更实用, 接下来我们会将h2标签中的内容动态显示。
完整代码请查看:divider.html。
2. 组件使用动态值
JSX语法会将花括号{…}之间的内容渲染为动态值。花括号指向了一个JavaScript上下文环境,任何放入花括号之间的内容都会进行求值,结果会被渲染为标签中的若干子节点。
花括号之间的内容,可是一个JavaScript变量名、函数、表达式。
2.1 使用变量名
使用变量名动态显示组件内容时可以像下面这样:
var text = 'Questions';
<h2>{text}</h2>
//<h2>Questions</h2>
完整代码请查看:dynamicValue-variable.html。
2.2 使用数组
当变量是一个数组时,React会对将数组中的每个元素渲染为一个节点:
var text = ['Hello', 'world'];
<h2>{text}</h2>
//Helloworld
数组渲染后HTML如下:
<div class="divider" data-reactid=".0">
<h2 data-reactid=".0.0">
<span data-reactid=".0.0.0">Hello</span>
<span data-reactid=".0.0.1">world</span>
</h2>
<hr data-reactid=".0.1">
</div>
完整代码请查看:dynamicValue-variable.html。
2.3 使用函数
对于更复杂的逻辑,我们可以将其封装成一个函数,并在花括号中调用这个函数:
function dateToString(d) {
return [
d.getFullYear(),
d.getMonth()+1,
d.getDate()
].join('-');
}
<h2>{dateToString(new Date())}</h2>
// 2016-1-23
从上面示例可以看出,花括号之间可以是任何有效的JavaScript表示式,大家可自行尝试更多用法。完整代码请查看:dynamicValue-function.html。
3. 子节点与组件复合
比起显示这些简单值,我们会希望沉渲染一些更复杂的数据,如,把数组中的数据分别渲染为若干个 h2。这时我们就需要使用子节点。
3.1 使用子节点
在前面的示例中,使用createClass()创建组件后,又使用render()将其渲染到了DOM(虚拟DOM)中。渲染到React DOM中的是一个ReactElement,而我们使用JSX语法时,JSX可以自动将其转换成一个ReactElement。因此,我们也可以像下面这样渲染组件:
ReactDOM.render(
<App></App>,
document.getElementById('example')
);
React对组件中花括号内的动态值的处理,会将其渲染成若干个组件。因此,我们可以通过定义组件的子节点属性来显示动态值:
var App = React.createClass({
render: function () {
return (
<div className="divider">
<h2>{this.props.children}</h2><hr/>
</div>
)
}
});
ReactDOM.render(
<App>itiblu.com</App>,
document.getElementById('example')
);
//<h2>itiblu.com</h2>
与HTML标签不同,JSX中组件要以大写字母开头。在上面示例中,我们在<App>标签之间插入了动态值,也就是子节点,而在组件中通过this.props.children属性引用子节点。可以看出,这种方式比使用JavaScript表示式更为简单易用。完整代码请查看:child.html
3.2 组件的复合
很多时候,子组件并不是一个,而是一个动态列表,这样我们就需要动态的创建子组件,并将其复合到父组件中。
我们可以像下面这样定义子组件,并实现的组件的复合:
var LiItem = React.createClass({
render: function() {
return <li>{this.props.data.name}</li>;
}
});
var App = React.createClass({
render: function () {
return (
<ul>
{this.props.results.map(function(result){
return <LiItem key={result.id} data={result} />;
})}
</ul>
)
}
});
var results = [
{id:'niefengjun.cn', name:'IT笔录'},
{id:'yijiebuyi.com', name:'一介布衣'},
{id:'niefengjun.cn', name:'老聂'}
];
ReactDOM.render(
<App results={results} />,
document.getElementById('example')
);
以上示例代码输出如下:
<ul data-reactid=".0"> <li data-reactid=".0.$itbilu=1com">IT笔录</li> <li data-reactid=".0.$yijiebuyi=1com">一介布衣</li> <li data-reactid=".0.$niefengjun=1cn">老聂</li> </ul>
与HTML属性类似,JSX语法中也定义了props,你可以像HTML属必一样将JSX属性传递到子组件中。完整代码请查看:child-dynamic.html
本文示例代码,请查看:demo2
