## 第五步: React速成教程
React是一个用于构建UI的JS库。你可以说它的竞争对手有AngularJS,Ember.js,Backbone和Polymer,尽管React专注的领域要小得多。React仅仅是MVC架构中的V,即视图层。
那么,React有什么特殊的呢?
React的组件使用特定的声明式样式书写,不像jQuery或其它传统JS库,你不与DOM直接交互。当背后的数据改变时,React接管所有的UI更新。
React还非常快,这归功于Virtual DOM和幕后的diff算法。当数据改变时,React计算所需要操作的最少的DOM,然后高效的重新渲染组件。比如,如果页面上有10000个已经渲染的元素,但只有一个元素改变,React将仅仅更新其中一个DOM,这是React为何能高效的重新渲染整个组件的原因。
React其它令人瞩目的特性包括:
* 可组合性。小的组件可以组合成大的、复杂的组件。
* 相对易于学习。需要学习的并不多,并且它不像AngularJS或Ember.js那样有庞大的文档。
* 服务端渲染。让我们能轻松的构建[同型JS应用(Isomorphic JavaScript apps)](https://medium.com/@mjackson/universal-javascript-4761051b7ae9)。
* 最有帮助的错误和警告提示,是我从未在其它JS库中见到过的。
* 组件是自包含的。标记、行为(甚至[样式](http://blog.vjeux.com/2014/javascript/react-css-in-js-nationjs.html))都在同一个地方,让组件非常易于重用。
我非常喜欢[React v0.14 Beta 1发布](http://facebook.github.io/react/blog/2015/07/03/react-v0.14-beta-1.html)中的这段话,讲了React到底是什么:
> 现在我们已经清楚,React的美妙和本质与浏览器或DOM无关,我们认为React的真正基础是关于组件和元素的质朴想法:用声明式的方式来描述任何你想渲染的东西。
在进入下一步之前,推荐你先观看这个了不起的视频[React in 7 Minutes](https://egghead.io/lessons/react-react-in-7-minutes),它的作者是John Lindquist,推荐你订阅PRO以获得更多的视频教程。
另外,也可以考虑Udemy上的这个广受好评的教程——[Build Web Apps with React JS and Flux](https://www.udemy.com/learn-and-understand-reactjs),作者是Stephen Grider。它包含超过71个视频和10小时以上的内容,涵盖了React,Flux,React Router,Firebase,Imgur API和其它。
当学习React时,我最大的挑战是使用完全不同的思考方式去构建UI。这也是为什么你必须阅读[Thinking in React](https://facebook.github.io/react/docs/thinking-in-react.html)([中文版](http://reactjs.cn/react/docs/thinking-in-react.html))这个官方指南的原因。
和Thinking in React中的产品列表风格类似,如果我们将*New Eden Faces* UI分开为潜在的组件,它将会是这样:
![](https://box.kancloud.cn/2015-09-14_55f6429e3d12e.jpg)
> 注意:每个组件都应该坚持单一职责原则,如果你发现你的组件做的事情太多,也许最好将它分成子组件。不过话虽如此,我首先还是编写了一个典型的的单块组件,当它能够工作后,然后将它重构为小的子组件。
在我们的项目中,顶级App组件包含Navbar,Homepage和Footer组件,Homepage组件包含两个Character组件。
所以,无论何时你想到一个UI设计,从将它分解为不同的组件开始,并且永远考虑你的数据如何在父-子、子-父以及同胞组件间传递,否则你会遇到这样的时刻:“WTF,这个到底在React里怎么实现的?这个用jQuery实现起来简单多了……”
所以,下次你决定用React构建一个新app时,在写代码之前,先画一个这样的层次大纲图。它帮你视觉化多个组件间的关系,并可以照着它来构建组件。
React中所有的组件都有`render()`方法,它总是返回一个单一的子元素。因此,下面的返回语句是错误的,因为它返回了3个子元素。
~~~
render() {
// Invalid JSX,
return (
<li>Achura</li>
<li>Civire</li>
<li>Deteis</li>
);
}
~~~
上面的HTML标记叫做[JSX](https://facebook.github.io/react/docs/jsx-in-depth.html)。它的语法和HTML仅有些微的不同,比如用`className`代替`class`,在我们开始开发应用的时候你将会学到它的更多内容。
当我第一眼看到这样的语法,我的第一反应就是拒绝,在JavaScript中我习惯返回布尔值、数字、字符串、对象以及函数,但绝不是这种东西。但是,JSX不过是一个语法糖。使用一个`<ul>`标签包裹上面的返回内容后,下面是不使用JSX时的模样:
~~~
render() {
return React.createElement('ul', null,
React.createElement('li', null, 'Achura'),
React.createElement('li', null, 'Civire'),
React.createElement('li', null, 'Deteis')
);
}
~~~
我相信你会同意JSX远比普通的JavaScript的可读性更好,另外,[Babel](http://babeljs.io/)对JSX有内建支持,所以我们无需做任何额外的事情即可解析它。如果你用过AngularJS中的指令(directive)那么你将会欣赏React的做法,这样你就不必同时处理两个文件——*directive.js*(负责逻辑)和*template.html*(负责展现),你可以在同一个文件里同时处理逻辑和展现了。
React中的`componentDidMount`方法和jQuery中的`$(document).ready`非常相似,这个方法仅在组件第一次渲染后运行一次(只在客户端运行),这里经常用于初始化第三方库和jQuery插件,或者连接到Socket.IO。
在`render`方法中,你将经常使用三元运算符:当数据为空时隐藏元素、根据条件注入CSS类名、根据组件的状态切换元素的展示等等。
比如下面的例子展示如果根据props值作为条件将CSS类名设为text-danger或text-success:
~~~
render() {
let delta = this.props.delta ? (
<strong className={this.props.delta > 0 ? 'text-success' : 'text-danger'}>
{this.props.delta}
</strong>
) : null;
return (
<div className='card'>
{delta}
{this.props.title}
</div>
);
}
~~~
这里我们仅仅浅尝辄止了React的内容,但这应该已经足以展示React的一般概念和它的优点了。
React本身是非常简单并且容易掌握的,但是,当我们谈起Flux架构时,可能会有些麻烦。
- 前言
- 概述
- 第一步:新建Express项目
- 第二步:构建系统
- 第三步:项目结构
- 第四步: ES6速成教程
- 第五步: React速成教程
- 第六步:Flux架构速成教程
- 第七步:React路由(客户端)
- 第八步:React路由(服务端)
- 第九步:Footer和Navbar组件
- 第十步:Socke.IO – 实时用户数
- 第十一步:添加Character的组件
- 第十二步:数据库模式
- 第十三步:Express API 路由(1/2)
- 第十五步:Home组件
- 第十四步:Express API 路由(2/2)
- 第十六步:角色(资料)组件
- 第十七步:Top 100 组件
- 第十八步:Stats组件
- 第十九步:部署
- 第二十步: 附加资源
- 总结