现在对React.js的欢迎程度正在疯狂的增长,也发生了许多有趣的事情,我的朋友大学同学都开始问我许多关于怎样学习Reat和怎样使用React的思想思考问题。
(2013年5月29号开始,谷歌搜索引擎搜索React的趋势图)
但是 React不是一个框架,它是一个概念,库和原则,用来让事情变得更快,以紧凑并且漂亮的方式在客户端和服务器端改进你的app。
在这篇博客的第三部分我会解释这些概念并且对于它用来做什么和怎样去用给一些建议,我们会讨论一些想法和技术。ES6 React
- virtual DOM
- Component-driven development
- Immutability
- Top-down rendering
- Rendering path and optimization
- Common tools/libs for bundling,ES6,request making,debugging,routing,etc.
- Isomorphic Reactok
ok,我们会写代码,让它尽可能的使用,在RisingStack GitHub repository所有文章中涉及到的代码片段都是直接可以使用的。
这篇文章首先从这三部分来介绍,让我们一起进入React的世界!
项目地址:
https://github.com/risingstack/react-way-getting-started
1.从React.js Tutorial开始React.js
如果你已经熟悉React并且了简单了解了它的基础知识,像virtual DOM的概念,组件概念等等,那么这篇React.js的介绍可能不是为你准备的。我们将讨论即将到来的众多部分的中心议题,它将会非常的有趣,读完之后我建议你再读一遍。
React是一个框架吗?
简言之:它不是
那么到底它是何方神圣,让如此的多的人对它痴迷疯狂
React 在应用程序中属于 视图 层,它也提供不同的方式去组织你的模板并且让你将它用做组件,在一个React的应用中,你应该将你的网站,页面,功能分成更小的多个组件,也就意味着你的网站有多个不同的
组件结合而成。这些组件也是有其他的组件组成的。当遇到一个难题非常有挑战性,那么你应该讲这个大的难题变成一个个更小难题,去各个击破。同样这个方式也是用于其他地方。
把它想象成 乐高玩具一样,接下来,我们将更深入的讨论组件驱动开发。
React也有虚拟DOM的概念,是什么让他渲染非常快的同时又非常容易理解和掌握。你可以把它和组件的思想和自上而下的渲染进行结合,在文章的第二部分我们会讨论这个主题。
ok,我承认,我仍然不能回答这个问题。我们又组建并且渲染得更快-但是为什么他是这个改变游戏规则的人?因为其似乎React主要是一个概念,其次是一个库。
已经有跟这个思想一样的库- 让他更快或者更慢-但是稍微有点不一样,跟其他每一个编程概念一样,React有他自己的解决方案,工具,库,使他成为一个完整的生态系统。在这个生态系统中,你必须选择你自己
的工具并且建立你自己的框架。我知道听起来非常可怕,但是请相信我,大部分的这些工具你已经了解了,我们只是将他们联系起来而已,你会非常惊讶于它是如此的简单,例如我们建立在以前的基础上,
没有使用任何魔法,然和节点的需要和 NPM。对于开源项目,我们会使用节点的时间触发器等其他的东西。(2015年1月,Facebook宣布用React.js Conf 中的React替换他们的框架,不过现在还不可用,第一次公开发布的日期还不知道)
2.简述下虚拟DOM的概念
追踪模型变换并且将他们应用于DOM,我们必须注意两件重要的事情
1.当数据已经改变的时候
2.那个(些)DOM元素被更新了
对于这些改变的检测,React用了观察者模型而不是粗暴的检查(持续不断的对于变化的检查)。那就是为什么不去预测什么
被改变了,它会立即知道。它降低了计算次数并且让app更加流畅。但是他真正的非常棒的思想是它对DOM的管理和控制:
对于DOM变化检测的挑战,React在内存中建立了DOM树来计算哪个DOM节点应该改变。对DOM的操作是重量级的,我们希望最低限度的较少花费。幸运的是,React尝试尽可能的保持不触碰其他的DOM元素
基于对象为单位,对更少的DOM节点的操作能计算得更快,DOM节点改变的花费也有效的降低了。
自从React比较算法 使用 树来表示DOM 并且 重新计算所有的子树,当他的父节点被改变(被粗暴的标记),你应该注意你的模型的变化,因为整个字数会被重新渲染,
不要失望,之后我们将一起优化这种情况。
追踪模型变换并且将他们应用于DOM,我们必须注意两件重要的事情
1.当数据已经改变的时候
2.那个(些)DOM元素被更新了
对于这些改变的检测,React用了观察者模型而不是粗暴的检查(持续不断的对于变化的检查)。那就是为什么不去预测什么
被改变了,它会立即知道。它降低了计算次数并且让app更加流畅。但是他真正的非常棒的思想是它对DOM的管理和控制:
对于DOM变化检测的挑战,React在内存中建立了DOM树来计算哪个DOM节点应该改变。对DOM的操作是重量级的,我们希望最低限度的较少花费。幸运的是,React尝试尽可能的保持不触碰其他的DOM元素
基于对象为单位,对更少的DOM节点的操作能计算得更快,DOM节点改变的花费也有效的降低了。
自从React比较算法 使用 树来表示DOM 并且 重新计算所有的子树,当他的父节点被改变(被粗暴的标记),你应该注意你的模型的变化,因为整个字数会被重新渲染,
不要失望,之后我们将一起优化这种情况。
怎样在服务器上也这样渲染?
实话说,这种DOM表示用的假DOM,它不可能渲染成HTML以及在服务器端输出(没有JSDom,PhantomJS etc.),React也足够智能的识别 标记已经在哪儿(来自服务器端) 并且只会在客户端增加事件处理。
在我们会用React写一个同构应用的第三篇文章中,这会是非常有用的
有趣的是:被渲染成HTML的React的标记包括 data-reactid属性,那将帮助React跟踪DOM节点
其他有用的链接,其他虚拟 DOM库:
The Secrets of React's virtual DOM
Why is React's concept of virtual DOM said to be more performant than dirty model checking?
3.组件驱动开发
这是我学习React中遇到的最难的部分之一。在组件驱动开发中,在一个模板中,你看不到整个站点,最开始,你可能会认为简直糟糕透了。但是我非常肯定的说你以后会意识到大问题化成许多小问题的强大,
并且工作中承担的责任更小。它让事情跟容易理解,维护和测试
我应该用它做什么呢?
下面我们来看下面的图片。这可能是一个功能或网站被分解的不同组件。每一个用不同的代表不同的简单组件的颜色来表示边框区域。根据这个,你就有了下面的组件层次结构。
FilterableProductTable
- SearchBar
- ProductTable
- ProductCategoryRow
- ProductRow
一个组件应该包含什么?
首先,遵循单一责任原则是明智的和理想的。把你的组件设计成仅仅以为一个事情具有代表性。当你觉得用你的组件做起来不是很顺的时候,你就应该把你的组件拆分成一个个更小的。
从我们开始讨论组件分层后,你的组件也应该使用其他的组件。但是让我们看下这个ES5组件的代码
var HelloComponent = React.createClass({ render: function() { return <div>Hello {this.props.name}</div>; } });但是从现在开始,我们将使用ES6。
让我们看下在ES6中跟ES5的同样的组件
class HelloComponent extends React.Component { render() { return <div>Hello {this.props.name}</div>; } }JS,JSX
正如你看到的,我们的组件中融合了JS和HTML的代码。等等,什么?在我JavaScript中竟然包含HTML?是的,可能你觉得不可思议(奇怪),但是在某方面这个思想代表一切。记住,
单一原则。它让一个组件及其灵活并且极好服用。
用React,你可以用纯JS写你的组件
render () { return React.createElement("div",null,"Hello ",this.props.name); }
但是我认为这种方式不太适合写你的HTML。幸运的是我们能用叫做JSX(JS扩展<一种可以让我们写内联HTML的东东>)语法的来写
render () { return <div>Hello {this.props.name}</div>; }什么是JSX呢?
JSX类似XML语法扩展的ECMAScript。JSX和HTML语法很相似,但是有一些点不同。例如,HTML中的class属性在JSX中中叫做className,其他的更深层次的不同之处可以看看Facebook的 "HTML Tags vs. React Components "
的指导。
因为默认情况下,JSX不是所有浏览器都支持。所有我们必须将他编译成JS。之后在安装部分我会写一些关于怎样使用JSX。(顺便说一下:Bable也能将JSX解析成JS)
非常有用的关于JSX的相关链接:
Babel: How to use the react transformer
其他的我们能增加的呢?
每一个组件都有一个内部状态,逻辑,甚至是包括处理程序(例如:按钮点击,表单输入东西的改变)并且也有内部样式。基本上包含所有需要显示的东东。
在代码片段中你可以看下这部分{this.props.name}。那意味着当我们建立完我们的组件结构后,我们可以通过改变属性改变我们的组件。就像: <MyComponent name="John Doe" />
他让我们的组件可复用并且让我们的应用状态从根组件传递给子组件,贯穿整个应用成为可能,他也是数据的必要部分。
看看下面一个简单的Rect app代码片段:
class UserName extends React.Component { render() { return <div>name: {this.props.name}</div>; } } class User extends React.Component { render() { return <div> <h1>City: {this.props.user.city}</h1> <UserName name={this.props.user.name} /> </div>; } } var user = { name: 'John',city: 'San Francisco' }; React.render(<User user={user} />,mountNode);有用的建立组件的链接
4.React拥抱ES6
在你的新的React项目中,没有其他的地方比ES6更好的值得尝试的了。
React不是来自于ES6语法,今天1月在版本v0.13.0中开始支持。
但是,这篇文章的讨论范围不会深入解释ES6;我们会使用他当中的组件,例如许多的类,arrows,consts 和 模块。例如,我们将从React.Component 类中继承我们的组件。
给出的ES6 只是被部分浏览器支持,我们将用ES6来写代码,之后会将他翻译成ES5并且将他能在所有的现代浏览器中能正常工作,哪怕没有ES6的支持。为了达到这个目的,
我们会使用Babel解析器。这儿有一个非常棒的并且非常简洁的对于ES6模块的介绍,我推荐大家可以看下这个:
关于ES6的有用的网址链接
5.用webpack和babel的绑定
我较早前提到过,我们将涉及到一些我们熟悉的工具并且用这些工具的组合来创建我们的应用。这第一个工具也是广为人知的就是node.js模块系统,他是一个包管理者,
我们会用 node 的风格写代码和规定我们需要的每件事情。React 就是一个像npm包一样简单并且可用。
我们的组件就会像这个样子:
// would be in ES5: var React = require('react/addons'); import React from 'react/addons'; class MyComponent extends React.Component { ... } // would be in ES5: module.exports = MyComponent; export default MyComponent;我们将要使用其他的 npm包,许多 npm包在客户端是有意义的。
比如我们会用debug去调试和搞定构成请求。
现在我们通过node就有了一个可依赖的系统。我们通过 npm几乎能解决所有的事情。那接下来呢?我们会选择我们最喜欢的库去解决我们的问题并且在客户端将他作为一个
单一的代码库给绑定在一起。为了达到这个目的,我们需要一个解决方案,让其在服务器上运行。
重点是我们需要选择一个绑定者。当今最著名的解决方案之一就是Browserify 和 Webpack 项目。现在我们正在使用Webpack,因为就我的经验看来Webpack 是React社区更加适合的首选的。
但是我也十分确定,你也能用Browserify达到同样的效果
它是怎样工作的?
Webpack将我们的代码和请求的包绑定到输出文件的。
实际上,Babel 这两件事都可以做。让我们来使用它吧!
我们做起来非常容易,因为Webpack 是配置型的
我们需要什么?首先 我们需要安装必要的模块
在你的终端运行下面的命令
npm install --save-dev webpack npm install --save-dev babel npm install --save-dev babel-loader创建完 webpack.config.js文件后
var path = require('path'); module.exports = { entry: path.resolve(__dirname,'../src/client/scripts/client.js'),output: { path: path.resolve(__dirname,'../dist'),filename: 'bundle.js' },module: { loaders: [ { test: /src\/.+.js$/,exclude: /node_modules/,loader: 'babel' } ] } };如果我们正确的完成,我们的应用将在./src/scripts/client/client.js开始,然后用webpack命令编译到./dist/bundle.js目录下面。
在这之后,你可以只需要在你的index.html页面引用bundle.js,如下:
<script src="bundle.js"></script>
(小贴士:你可以使用node-static命令,并安装依赖模块,以便启用你的站点。npm install -g node-static ,然后从static . 去使你文件夹的内容展示到这个地址: 127.0.0.1:8080.)
6.设置项目
现在我们已经安装并且配置了W恶补P啊出口和Babel属性。但是在每个项目中,我们都需要一个项目结构。
文件夹结构
我更喜欢采用下面的项目结构:
config/ app.js webpack.js (js config over json -> flexible) src/ app/ (the React app: runs on server and client too) components/ __tests__ (Jest test folder) AppRoot.jsx Cart.jsx Item.jsx index.js (just to export app) app.js client/ (only browser: attach app to DOM) styles/ scripts/ client.js index.html server/ index.js server.js .gitignore .jshintrc package.json README.md
这个想法在这个结构之后是为了将React app从客户端和服务器端的代码分离出来。因为我们的React app可以同时在客户端运行和服务器端运行。(=isomorphic app,我们将会在之后的博客中深入的探讨这个问题)
7.怎样测试我的React应用
当我们接触一个新的技术的时候,最重要的一些问题都应该测试。如果没有测试,你就是在玩火。
那我们应该使用什么测试框架呢?我的经验告诉我,前端最好的测试是有他的开发者来完成。因此,我用Jest来测试我的app应用。Jest是facebo出的一个测试框架。
Jest还有很多强大的功能,在本文我不一一介绍。
我觉得讨论Reat app的测试时非常重要的。幸运的是,单一原则是我们的组件只做一件事情。所以我们只是专注于测试那一件事情。通过组件的属性,触发事件,查看渲染出来的样子,听出来很容易,实际也如此。
要看更多的实际的例子,可以下载React.js的辅助文档。
测试JSX和 EX6文件
去测试我们EX6语法和JSX文件。我们应该将他们翻译成Jest.Jest有一个你可以定义的预处理其的配置变量。
首先我们应该定义一个预处理器,然后把路径传给Jest.在我们的知识库中,你可以找到一个可运行的例子。
jet也有一个叫做 React ES6 testing 的例子。
8.赠送的
在本文中,我们会探讨为什么React速度非常快并且扩展性很好,但是他的方法又非常不同。怎样渲染,组件驱动开发是什么,你怎样创建,组织你的项目,这些都是基础。
在接下来的“the react way”这篇文章中,我们将深入的探讨。
我任然相信,学习一个新的变成思想最重要的方式就是开发和写代码。
那就是为什么我想叫你去写一些非常棒的东西并且花一些时间查看官方的react web站点,尤其是导航部分。良好的资源,facebook的开发者,还有react社区的人一起做了这个非常棒的事情。
9.下一步
如果你喜欢这篇文章。订阅我们的邮件,其余关于React的东西你就会很快获得。
我们会讨论的一些有趣的话题。
希望很快见到你,在那之前,丰富你的知识库
原文地址:http://blog.risingstack.com/the-react-way-getting-started-tutorial/