我是“浏览器内设计”( in Browser Design ) 的超级粉丝,但是如果没有一个舒适的调试前端界面的环境,那么设计过程就会很不爽。像我直接的前端代码都是 Rails 项目的一部分,每次要改动点内容,页面刷新都会很慢(也许是因为我机器慢,但也是由于每次页面刷新都要走 Rails Asset Pipeline 的处理流程,并且页面数据要去读数据库,所以页面反应很慢)。总之,我希望有一套更好的前端调试环境,让 In Browser Design 变得愉悦。
我要达成下面几个目标:
尝试了一些方案,最终发现使用 Facebook 的 Reactjs 可以很好的达成我的要求。所以这集开始连载几期好多视频来聊聊 React 的各种优势。
React 经常会被拿来跟 Angular Backbone 这些前端框架拿来比较,这个当然不是没有原因,但是也不是完全正确的比法。因为 React 本身不是框架,只是一套写前端界面的新手段,只是 MVC 中的 V ( View )的部分。所以后面会看到,即使是最基本的 React 使用,其实也是要配合 Gulp ,Browserify 等其他工作来完成的。顺便扯一句,Nodejs 也不是框架,但是也经常被拿来跟 Rails 做比较,其实有道理,因为大家都是用来做一类工作的,nodejs 引领的是一种新方式, react 也一样。
在 React 官网 上可以看到列出的 React 的核心的三个卖点,我来分别说说我的体会。第一,“Just the UI” ,只是界面,意思是没有 Controller ,这个就跟 Angular 这些 MV* 的框架区分开了,所以 React 可以灵活一些。但是一般要给 React 加 M 和 C( model 和 controller )就用 Flux 架构 。第二,“Virtual Dom” 可以大大提高渲染速度,这里还提到了 React-native , 可以用来开发真正的手机本地应用,这个真的实现了,也会是革命性的(注意,不是 WebView 套网页那种,是真正的 Native 应用 )。第三个,”Data Flow“ ,单向数据流有高手说这种思想是醍醐灌顶的,我暂时写的都是小东西还体会不到。靠,要提一下的是看了一些网上的 React demo ,真的可以写出非常复杂的界面出来,被震住了。
我自己学习 React 的基础知识是从 这套英文教程 还有 laracasts 上的 React 课程 开始学的,这两套都是真正的基础教程,非常适合入门的。中文资源我发现了 React 教程 。
实际使用咱们还是看视频吧,我会按照我自己要搭建的环境为方向,但是每一步都放慢节奏来演示,这样大家保持同步,看文档就不会痛苦了。视频中先使用 react 自己的功能来写一个页面,咱们一起来看看 jsx 到底怎么用。视频中涉及到的一些重要概念列在下面了:
定义一个元器件用下面的语句
<body>
<div id="app"></div>
<script type="text/jsx">
var HelloWorld = React.createClass({
render: function(){
return (
<div> Hello World </div>
)
}
});
React.render(<HelloWorld />, document.getElementById('app'));
</script>
</body>
上面 script 标签内不是标准的 js 语句,所以要用 JSXTransformer 把它编译成合法的 js ,另外代码要运行还需要 react.js 。 可以到 http://www.bootcdn.cn/react/ 来使用国内的 CDN :
<script src="http://cdn.bootcss.com/react/0.14.0-beta2/JSXTransformer.js"></script>
<script src="http://cdn.bootcss.com/react/0.14.0-beta2/react.js"></script>
注意我在上面两个链接前面都添加了 http:
这样打开页面的时候就不用起 server 了。另外 JSXTransformer 只是在开发环境下需要,要产品部署之前,我们都会把 JSX 先做预处理变成合法的 js 代码,所以产品部署的时候可以把引用它的那一行去掉。
另外插一句,Facebook 的 html 变 JSX 的编译器 可以把普通的 html 转换成 JSX 文件中合法的 xml 标签,其实二者差别不是特别大,例如 html 中用的 class
现在要写成 className
了。
一个页面上可以有多个元器件,每个元器件内部还可以有子有孙。
如果我定义一个 Child 元器件,然后嵌入到 Parent 元器件之中使用,也就是有下面的代码
<script type="text/jsx">
var Child = React.createClass({
render: function(){
return (
<div> The Child </div>
)
}
});
var Parent = React.createClass({
render: function(){
return (
<div> Hello World </div>
<Child/>
)
}
});
React.render(<Parent />, document.getElementById('app'));
</script>
实际运行一下,浏览器会报错,我们需要给 Parent 中的
<div> Hello World </div>
<Child/>
这些代码外面套上一层标签,比如一级 div 。原因?让 return
可以返回一个元素,而不是多个元素,多个 DOM 节点。
后面文件大了,要写的 jsx 代码多了,就要考虑单独分出 xxx.jsx 文件,这时候固然可以用 script 标签来引入这些文件,但是如果我们有几百个元器件呢?这样就要写一堆 script 标签了。所以好的方式是用 require ,这样就要用到 Browerify 了。
今天先写到这里,Peter 需要的的” In Browser Design 的环境现在还没弄出来,后续还会引入 Gulp&Watchify 的实时编译, react-router 路由功能,browsersync 的页面自动刷新以及其他一些辅助功能。好多视频上的内容常被大家批评说太零散,所以,做过广告啊,React 相关的内容会放到这个仓库里 http://github.com/happypeter/react-book ,大家可以尽情 Star ,回头会出书的。
另外,国内 React 社区火爆,大家有问题可以去 http://www.react-china.org/ 上面问。