ReactJS小记(2)

By | 2015/12/17

上一次我们简单的新建了一个组件,不过这个组件实在太简单了,根本无法把Components的优点表达出来,更主要的是,这个组件完全是静态的,这么一来,我们不如直接写HTML好了呀。

Props属性

props用于定义在新建组件时的属性,在组件的代码中,我们可以使用this.props来获取,光这么说太过抽象,我们来关门放代码……

运行它,我们可以看到原来的world被新建组件时传入的xishui所代替(居然想代替世界好大的胆子:-)。

组件的嵌套

在React中,一旦你创建了一个组件,你就可以把它当作一个标准的html标签用了,什么意思呢?我们上面的组件是用标准的<div>创建的,而事实上,我们完全可以使用另外的组件来创建一个新的组件!

好复杂好复杂,我们创建了四个组件呢,其中CommentBox用到了CommentList和CommentForm,而CommentList又用到了Comment,这样嵌套的使用组件也是完全么有问题的!事实上你也应该学会这么使用。

  • CommentBox – 最高级的组件,展示了整个留言App的界面
  • CommentList – 留言列表组件,调用Comment组件
  • CommentForm – 留言框组件,用于接收用户输入
  • Comment – 留言组件,用于展示一条留言
20151216151714

执行效果的话,就是这个样子

顺便看看Comment中,我们还用到了一个this.props.children,这是一个特别的属性,代表了书写组件标签内部的所有内容。

事件和状态

我们知道了Components初始化的时候传入的参数可以使用this.props来获得,但是这好像并没有多少改善吧……因为传入的数据不是一成不变的啊,Web页面或者说Web的UI就是要发生改变才有趣嘛。

再给大家介绍一位小兄弟this.state,事实上他可能比this.props更为重要,因为State是保持组件现有数据的一个属性,当你使用setState方法设置state属性的时候,React就会触发刷新UI的动作。如果你想在组件初始化的时候设置一下state,记得使用getInitialState。我们还是用一个例子来说明一下这个东西。

CommentBox又变复杂了一点,我们还增加了一个自定义的方法,用来增加count的值,而为了调用这个方法,使用了很常规的按钮,注意这里的onClick大小写要正确,包括<br />也要正确闭合,因为JSX是一种XML,无法适应html宽松的写法,我们要严格一些才行。

上面的效果就是,点一下按钮,comments的数量就会+1,当然改的只是那个数字,留言本身的条数还没有变化。

其实有件事情一开始出现了,我一直忍住没说……所有涉及到Components的属性或者方法的地方,我们都用了{}来包裹,这也是React的规定,如果不这么写,编译器很难判断这个到底是个表达式还是一个字符串。

有了getInitialState,有没有getInitialProps呢?否则如果新建Components的时候没有传入值想用默认的怎么办?你说的没错,React有这么一个东西,不过名字叫getDefaultProps,其实也很好理解,属性是默认的,状态是初始化后才有的。

除了HTML中的一些事件,React还专门为Components加了几个事件,事实上这也是组件生命周期上几个事件,罗列如下:

  • componentWillMount – 在第一次挂载的时候执行。
  • componentDidMount – 在第一次挂载完成后执行,这是一个用来加载远程数据的好地方。
  • shouldComponentUpdate – 每次重新渲染前执行,可以返回一个false值来阻止UI更新。
  • componentWillUnmount – 在挂载取消前执行。

我们再来为我们的程序引入更多的活力,那个CommentForm不是还空空如也么,就在这里开刀:

不得不说,与Angular的双向绑定相比,这个写法还是有点麻烦的……我们为文本框绑定了change事件,每次都捕获用户的输入,然后设置回去;我们同时捕获了表单的提交事件,阻止浏览器的默认提交动作,然后将用户输入的东西打了出来。

再来看看最常用的循环表示一个列表是怎么做的,CommentList里的数据还都是写死的,用一个变量来表示吧:

React中对于数据的循环并没有引入一些自定义的方法,而是纯粹是用了JS原生方法,当然如果你对map不熟悉,使用for循环也是可以的(这样的话{}里可以调用一个函数,这个函数的返回值就是拼接的结果)。

有一个注意点是Comment属性里我们加了一个key,这是React推荐的做法,当提供一组循环的组件时,最好为每一个子组件带上唯一的key值,如果你不这么做,React会给出一个警告。我们这里简单的使用了index来作为key,其实不是一个好方法,最好每个comments里每一个元素都有自己的标识(就好像数据表里的主键),不过这里为了简单,我们暂时这么写。

好了,我们都知道下面要做什么了,这么几个组件得有机的结合起来才行——当我们在CommentForm中输入一点什么的时候,我们希望把输入的东西加到CommentList中去。这里牵涉到组件之间的相互关联,我们看看React是怎么解决这个事情的。注意上方的CommentList将数据直接自己保管了,为了通讯上的方便,我们应该把数据交给最高层的CommentBox来管理;而不同层级间方法的调用,我们其实可以使用props值之间传入方法。为了方便对比纠错,把babel代码全部粘上:

最终效果如下图:

react-comment-box1

好了,现在我们已经学习了React的一些基本概念了,包括JSX,组件,以及一些常见的API。我们最后做了一个本地的Web App(数据都是存放在js变量里的),如果您有一些ajax的基础,可以很容易的把它改写成与服务器同步的应用。

下一次我们来说说React的一些更深层次的东西,大概会是Flux或者React编程思想吧(笑)。


发表评论

电子邮件地址不会被公开。 必填项已用*标注