我们使用 React 来编写用户界面。在这里,您可以找到我们选择 React 的原因以及简要介绍。此外,我们列出了所有 DevTools 代码在编写 React 时应遵循的最佳实践。
快速入门¶
这是一个关于如何使用 React 的非常简短的介绍,但没有深入解释其背后的概念。如果您想了解更多深入的文章,我推荐以下链接
http://facebook.github.io/react/docs/tutorial.html - 官方教程
https://github.com/petehunt/react-howto - 如何学习 React
http://jlongster.com/Removing-User-Interface-Complexity,-or-Why-React-is-Awesome - 阅读量很大,但深入解释了概念
React 将组件作为思考 UI 的一种方式。组件是所有事物的中心:它们像函数一样可组合,像 JSON 数据一样可测试,并为更复杂的情况提供生命周期 API。
一个组件可以代表任何东西,从列表中的单个项目到由子组件组成的完整虚拟网格。它们可以用来抽象出“行为”而不是 UI 元素(想想 Selectable
组件)。React 的 API 使您能够轻松地将 UI 分解成您需要的任何抽象。
组件的核心思想很简单:它接收属性并返回类似 DOM 的结构。
function Item({ name, iconURL }) {
return div({ className: "item" },
img({ className: "icon", href: iconURL }),
name);
}
div
和 span
函数分别指代 React.DOM.div
和 React.DOM.span
。React 在 React.DOM
上为所有 DOM 元素提供了构造函数。这些符合创建元素的标准 API:第一个参数接收属性,其余的是子元素。
您可以看到在使用 Item
时组件组合开始发挥作用。
const Item = React.createFactory(require('./Item'));
function List({ items }) {
return div({ className: "list" },
items.map(item => Item({ name: item.name, icon: item.iconURL)));
}
您可以像使用原生组件一样使用自定义组件!唯一的区别是我们在导入时将其包装在一个工厂中,而不是使用 React.DOM 函数。工厂只是将组件转换为便捷函数的一种方式。如果没有工厂,您需要执行 React.createElement(Item, { ... })
,这与使用工厂时的 Item({ ... })
完全相同。
渲染和更新组件¶
现在我们有一些组件了,我们如何渲染它们?您可以使用 React.render
来实现。
let items = [{ name: "Dubois", iconURL: "dubois.png" },
{ name: "Ivy", iconURL: "ivy.png" }];
React.render(List({ items: items }),
document.querySelector("#mount"));
这将渲染一个 List
组件(给定 items
)到 ID 为 mount
的 DOM 节点。通常,您有一个作为所有内容根的顶级 App
组件,您可以像这样渲染它。
更新怎么办?首先,让我们谈谈数据。上面的组件从上面获取数据并渲染出 DOM 结构。如果涉及任何用户事件,组件将调用作为 props 传递的回调函数,因此事件会向上回溯层次结构。概念模型是数据向下传递,事件向上回溯。
您通常希望响应事件更改数据,并使用新数据重新渲染 UI。那是什么样子?React 将在两个地方重新渲染组件
1. 任何额外的 React.render
调用。一旦组件被挂载,您可以再次对相同位置调用 React.render
,React 将看到它已经挂载并执行更新而不是完全渲染。例如,此代码响应事件添加一个项目并更新 UI,并将执行最佳增量更新
function addItem(item) {
render([...items, item]);
}
function render(items) {
React.render(List({ items: items,
onAddItem: addItem }),
document.querySelector("#mount"));
}
render(items);
2. 更改组件本地状态。这更为常见。React 允许组件具有本地状态,并且只要使用 setState
API 更改状态,它就会重新渲染该特定组件。如果您使用组件本地状态,则需要使用 createClass
创建组件。
const App = React.createClass({
getInitialState: function() {
return { items: [] };
},
handleAddItem: function(item) {
const items = [...this.props.items, item];
this.setState({ items: items });
},
render: function() {
return List({ items: this.state.items,
onAddItem: this.handleAddItem });
}
});
如果您使用 Redux 等内容来管理状态,则通过用于将 Redux 与 React 绑定的库自动为您处理。请参阅 Redux 中的更多信息。
DOM Diff¶
当 React “更新”组件时这意味着什么,它如何知道要更改哪个 DOM?React 通过一种称为 DOM Diff 的技术实现了这一点。这避免了程序员需要担心更新实际上是如何应用于 DOM 的,并且组件可以响应数据以声明方式渲染 DOM 结构。在上面的示例中,当添加项目时,React 知道仅添加一个新的 DOM 节点,而不是每次都重新创建整个列表。
DOM Diff 是可能的,因为我们的组件返回所谓的“虚拟 DOM”:React 可以用来与先前版本进行比较并生成对真实 DOM 的最小更改的轻量级 JSON 结构。
这也使使用真实 DOM 测试组件变得非常容易:只需确保虚拟 DOM 包含它应该包含的内容即可。
下一步¶
接下来阅读 React 指南,了解如何专门为 DevTools 编写 React 代码。