ReactJS小记(1)

By | 2015/12/15

坑永远不嫌多的,记得之前说过要更新EmberJS教程的,但是最近感觉React如日中天,就连Angular也难掩其光辉,React Native出来后更是如此,虽说是两个东西,但是两者还是有很多共通之处的,React Native入手之前,学习学习ReactJS总是没错的,所以……来挖这个坑吧!

话说Twitter贡献了个Bootstrap,Facebook贡献个ReactJS(当然我知道他们贡献的远远不止这些),两个“不存在”的网站,都干的不错嘛~

React的教程不少,甚至有官方文档的中文翻译了,不过现在React已经更新到0.14.3了(2015/12/15),翻译的教程依然停留在0.13。而0.14后,react有了比较大的变化,可能让下载了新的库却又面对着旧的文档的同学有些不知所措。虽然老的写法可能还是有效的,但是官方已经不推荐那么写了,而且0.15后可能会剔除兼容的写法,所以还是跟随官方来吧。

本系列教程以最新的0.14.3为模板书写,面向初学者,其实就是个入门,精通什么的……大家看看就好了。

在这个下载页面,可以下载最新的Starter Kit,可以理解成基本的必须文件,用这个就不用各个地方去下库了,即时解压就能用。

要去用什么JS编辑器,html的基础什么的我就不说了啊,稍微介绍一下React。

React是什么?

React是Facebook开发的一个UI库,用于制作“可重用、高交互性、带状态”的UI组件。Facebook在2013年就开源了这个东西,它的很多网站也使用这个来书写,现在的话使用React开发的网站越来越多了,Instagram.com(好吧也被墙了)就是一个完全使用React编写的站点。

React高效而灵活,它有一个特点是可以在服务端执行渲染然后传给客户端,当时一定是个很惊艳的想法,不过得益于Node.js的流行,现在很多js库都这么弄了,所以听起来也不是那么有亮点了。

React最厉害的概念其实是虚拟DOM( Virtual DOM) ,这个确实颇为新颖,直到现在这么做的UI框架也没几个,它维护了一棵表示所有节点状态的树,当数据发生变化时,React查看到底是哪些节点发生了变化,然后在页面上绘制出来。

虚拟DOM是个怎么回事?

内部一棵UI树,然后再画出来,听起来好像有点多此一举,但是实际上,在Web的世界,JavaScript很快而DOM很慢,重绘界面是很花时间的,React有一个不错的Diff算法,可以很高效的找到哪些节点发生了变化,然后只需要在界面上局部地更新那几个节点,这样其实也算一种用空间换时间的做法。事实证明,这个方法还真挺好用的……

而且不知道是不是无心插柳,虚拟DOM很好的解决了不同终端的显示问题,只要最后改一下显示的方法就行了,而内部的UI组件甚至逻辑都可以完全是一致的,React的服务器渲染也因为这个思想得到了实现,而React Native也就乐呵呵的出来吸粉了:)

开始吧

上面那个Starter Kit下载下来了吧,解压它,里面有个examples文件夹,你可以打开几个项目看看……

看完了?是不是有几个还没啥反应,那是需要后台服务器支持的,咱先不管~

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>React</title>
  </head>
  <body>
    <div id="mount-point">
    </div>

    <script src="../../build/react.js"></script>
    <script src="../../build/react-dom.js"></script>
    <script>
      // some react code
    </script>
  </body>
</html>

上面是个最简单的React框子,仅仅是引入了react和react-dom两个库。

顺便说一下,以前react-dom是和react一起的(0.14以前),但是Facebook意识到,dom这个东西毕竟只是Web上的概念,其他的界面比如手机UI上就是没有的,所以就把React-DOM独立出来了,我们Web开发肯定要带上它,而App开发就不需要了。

React所有的组件需要挂载到一个实际的节点上,我们这里用了一个叫mount-point的div,过会儿魔法也就在这里施展。

再顺便说一下……js放在body的最后是一种最佳实践,应该大家都知道了吧?

我们来写一点react的代码

<script>
        ReactDOM.render(
          React.createElement('h1', null, 'Hello, world!'),
          document.getElementById('mount-point')
        );
</script>

OK,执行页面,你可以看到Hello, world!了!

如果你写过一些JS代码,或者使用过一些JS的库,但又是React的初学者,相信你有海量的槽想吐,其中最有可能的一句应该就是“我去这也太麻烦了吧?!”

没错,如果使用jQuery,$("#mount-point").html("<h1>Hello, world!</h1>")就完事了,这个相比实在是太繁琐了。但如果您因此给React判了死刑,那可真是放弃了一片星辰大海啊。我们现在先来把这个例子稍微简化一丁点~

引入一个新的JS,你可以直接下下来或者使用cdn上的,http://cdn.bootcss.com/babel-core/5.8.34/browser.min.js。browser.js是什么呢?它自我介绍说是用来识别次世代javascript写法的工具,听起来好像牛气冲天哇,可别说,还真是这么一回事,我们把react代码这么改写一下。

<script type="text/babel">
    ReactDOM.render(
      <h1>Hello, world!</h1>,
      document.getElementById('mount-point')
    );
</script>

心急的朋友立刻跳出来了,“你这个写法根本就不对,语法错误!”,不要这么急嘛,你先试试?

如果你试了还是报错,那么请检查,有没有正确引入browser.js,然后最重要的,看看script的type有没有设置正确,应该是text/babel。什么是babel,这个暂时不重要,就知道这是一种JS的模板好了,我们要知道的是,这种像极了XML的JavaScript的写法,它叫JSX。JSX可是非常重要的东西,也是React引入的。以前的版本,可能是引入JSXTransformer.js,并且script标记为text/jsx,不过既然官方已经摒弃了这种用法,我们也只能随大流了,而且实际上,官方提供一个babel-cli的编译器,可以把我们的babel脚本编译成合法的javascript脚本,这个暂时先不说,以后有机会再讲,我们现在只要使用这种browser.js的方法就好了。

Components组件

当我们使用了ReactDOM的render方法的时候,第一个参数就是一个组件,第二个参数则是挂载的节点。组件可以是html标签,也就是我们上面使用的React.createElement和JSX,除此之外还有一种更为强大的React.createClass,它可以用来创建自定义组件,举个例子:

<script type="text/babel">
var CommentBox = React.createClass({
  render: function() {
    return (
      <div className="commentBox">
        Hello, world! I am a CommentBox.
      </div>
    );
  }
});
ReactDOM.render(
  <CommentBox />,
  document.getElementById('mount-point')
);
</script>

这个组件只是一个简单的div,我们创建了一个Component之后,就可以使用JSX宛若原生的HTML标签那样使用它了,为了以示区别,我们一般把自己定义的组件用大写字母开头,而原生的像div之类的,都是小写字母。

也许你会问div的class为什么写成了className,那id也要写成idName吗?事实上因为class和for是JS的关键词,所以仅有这两个属性发生了一点变化,分别是className和htmlFor,其他的还是熟悉的味道~

不过Components远没有这么简单,我们下次来说说创建组件时的一些高级点用法。

 

One thought on “ReactJS小记(1)

puyangsky进行回复 取消回复

您的电子邮箱地址不会被公开。