ThinkChat2.0新版上线,更智能更精彩,支持会话、画图、阅读、搜索等,送10W Token,即刻开启你的AI之旅 广告
## 第五步: 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架构时,可能会有些麻烦。