用户界面能做的最基础的事就是呈现一些数据。React 让显示数据变得简单,当数据变化时,用户界面会自动同步更新。
让我们看一个非常简单的例子。新建一个名为 hello-react.html
的文件,内容如下:
<!DOCTYPE html>
<html>
<head>
<title>Hello React</title>
<script src="http://fb.me/react-0.14.7.js"></script>
<script src="http://fb.me/JSXTransformer-0.14.7.js"></script>
</head>
<body>
<div id="example"></div>
<script type="text/jsx">
// ** 在这里替换成你的代码 **
</script>
</body>
</html>
在接下去的文档中,我们只关注 JavaScript 代码,假设我们把代码插入到上面那个模板中。用下面的代码替换掉上面用来占位的注释。
var HelloWorld = React.createClass({
render: function() {
return (
<p>
Hello, <input type="text" placeholder="Your name here" />!
It is {this.props.date.toTimeString()}
</p>
);
}
});
setInterval(function() {
React.render(
<HelloWorld date={new Date()} />,
document.getElementById('example')
);
}, 500);
在浏览器中打开 hello-react.html
,在输入框输入你的名字。你会发现 React 在用户界面中只改变了时间,你在输入框的输入内容会保留着,即使你没有写任何代码来完成这个功能。React 也为你解决了这个问题,做了正确的事。
我们想到的解决方案是React 是不会去操作 DOM 的,除非不得不操作 DOM 。它用一种更快的内置仿造的 DOM 来操作差异,为你计算出效率最高的 DOM 改变。
这个组件的输入被称为 props
- "properties"的缩写。它们通过 JSX 语法进行参数传递。你必须知道,在组件里这些属性是不可直接改变的,也就是说 this.props
是只读的。
React 组件非常简单。你可以认为它们就是简单的函数,接受 props
和 state
(后面会讨论) 作为参数,然后渲染出 HTML。正是由于它们如此简单,使得它们非常容易理解。
注意:
一个限制: React 组件只能渲染单个根节点。如果你想要返回多个节点,它们必须被包含在同一个节点里。
我们始终坚信,组件使用了正确方法去做关注分离,而不是通过“模板引擎”和“展示逻辑”。我们认为标签和生成它的代码是紧密相连的。此外,展示逻辑通常是很复杂的,通过模板语言实现这些逻辑会产生大量代码。
我们得出解决这个问题最好的方案是通过 JavaScript 直接生成模板,这样你就可以用一个真正语言的所有表达能力去构建用户界面。为了使这变得更简单,我们做了一个非常简单、可选类似 HTML 语法 ,通过函数调用即可生成模板的编译器,称为 JSX。
JSX 让你可以用 HTML 语法去写 JavaScript 函数调用。 为了在 React 生成一个链接,通过纯 JavaScript 你可以这么写: React.createElement('a', {href: 'http://facebook.github.io/react/'}, 'Hello React!')
。通过 JSX 这就变成了 <a href="http://facebook.github.io/react/">Hello React!</a>
。我们发现这会使搭建 React 应用更加简单,设计师也偏向用这种语法,但是每个人都有自己的工作流,所以JSX 并不强制必须使用的。
JSX 非常小;上面“hello, world”的例子使用了 JSX 所有的特性。想要了解更多,请看 深入理解 JSX。或者直接使用在线 JSX 编译器观察变化过程。
JSX 类似于 HTML,但不是完全一样。参考 JSX 陷阱 学习关键区别。
最简单开始学习 JSX 的方法就是使用浏览器端的 JSXTransformer
。我们强烈建议你不要在生产环境中使用它。你可以通过我们的命令行工具 react-tools 包来预编译你的代码。
你完全可以选择是否使用 JSX,并不是 React 必须的。你可以通过 React.createElement
来创建一个树。第一个参数是标签,第二个参数是一个属性对象,第三个是子节点。
var child = React.createElement('li', null, 'Text Content');
var root = React.createElement('ul', { className: 'my-list' }, child);
React.render(root, document.body);
方便起见,你可以创建基于自定义组件的速记工厂方法。
var Factory = React.createFactory(ComponentClass);
...
var root = Factory({ custom: 'prop' });
React.render(root, document.body);
React 已经为 HTML 标签提供内置工厂方法。
var root = React.DOM.ul({ className: 'my-list' },
React.DOM.li(null, 'Text Content')
);