和 Facebook 的 Reactjs 在一起的第一天
2015年8月7日

我是“浏览器内设计”( in Browser Design ) 的超级粉丝,但是如果没有一个舒适的调试前端界面的环境,那么设计过程就会很不爽。像我直接的前端代码都是 Rails 项目的一部分,每次要改动点内容,页面刷新都会很慢(也许是因为我机器慢,但也是由于每次页面刷新都要走 Rails Asset Pipeline 的处理流程,并且页面数据要去读数据库,所以页面反应很慢)。总之,我希望有一套更好的前端调试环境,让 In Browser Design 变得愉悦。

我要达成下面几个目标:

尝试了一些方案,最终发现使用 Facebook 的 Reactjs 可以很好的达成我的要求。所以这集开始连载几期好多视频来聊聊 React 的各种优势。

React 不是框架

React 经常会被拿来跟 Angular Backbone 这些前端框架拿来比较,这个当然不是没有原因,但是也不是完全正确的比法。因为 React 本身不是框架,只是一套写前端界面的新手段,只是 MVC 中的 V ( View )的部分。所以后面会看到,即使是最基本的 React 使用,其实也是要配合 Gulp ,Browserify 等其他工作来完成的。顺便扯一句,Nodejs 也不是框架,但是也经常被拿来跟 Rails 做比较,其实有道理,因为大家都是用来做一类工作的,nodejs 引领的是一种新方式, react 也一样。

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 元器件

实际使用咱们还是看视频吧,我会按照我自己要搭建的环境为方向,但是每一步都放慢节奏来演示,这样大家保持同步,看文档就不会痛苦了。视频中先使用 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/ 上面问。