React使用总结

两种架构

如今使用React的开发模式主要有两种——freeMarker+React以及纯静态React页面开发。本文着重介绍纯静态React页面的开发方式。html

freeMarker+React

因为之前是用YUI+freeMarker进行开发,为了保证之前的页面都可以正常访问,当重构老页面时会使用这种开发方式。
在这种开发模式下由java利用freeMarker生成并Render为html,经过browserify将js打包至资源目录并在browser中加载,React将app render至div中。java

React纯静态页面

利用browserify使用同构的方式进行开发,直接产出html以及js文件放置到资源文件中经过文件路径访问页面。采用这种方式开发有如下优势:node

  • PreRender产出的静态资源文件加载速度快
  • 先后端只经过ajax进行交互,使得先后端分离,各自约定好接口以后就能进行开发。
  • 同构的开发模式使得功能模块能够复用,好比模板、node的一些经常使用模块等等。

须要注意代码能同时在browser与node环境下执行,不然会出问题。当使用bom对象时,在componentDidMount生命周期中运行,此时node环境下已经完成了first render。react

构建方式

在node环境下经过React.renderToString方法生成html,经过这种方式生成的标签会带有data-reactid属性,储存server render结果的校验值。
当在browser中React.render时会检查校验值是否一致,保证node以及browser环境下render的结果一致。所以开发过程当中必定要保证render的结果保持一致,若是须要在browser中插入dom节点,可使用insert等操做。禁止state以及props在两个环境下值不一样。
若是经过校验,则React不会从新生成dom,只将事件监听器挂载在对应的节点下。ajax

应用架构

采用flux的思想来组织应用,具体的方案我推荐facebook的flux或者reflux,这也是如今Github中获星最多的flux实现方案。二者的主要区别是reflux不经过Dispatcher来控制action的分发,reflux中使用了较多的magic来使得代码更加简洁高效。后端

若是项目的复杂程度不高(没有多个互相关联的store),我推荐使用Reflux,通常状况下其实一个store就够了,并且避免了处理store之间的通讯问题。数据结构

╔═════════╗       ╔════════╗       ╔═════════════════╗
║ Actions ║──────>║ Stores ║──────>║ View Components ║
╚═════════╝       ╚════════╝       ╚═════════════════╝
     ^                                      │
     └──────────────────────────────────────┘

若项目较为庞大,考虑到代码的可控性、直观,以及更好地去控制各store之间的响应逻辑,使用flux更合适。架构

优势

采用flux来构建应用有如下优点:app

  1. 将state在store中统一进行管理,实现业务与组建的分离,代码结构更加清晰。
  2. 因为action在store中进行监听,所以事件不须要再一层层经过props来进行传递,简化代码,并且也更容易将应用拆分红更细粒度的模块。
  3. 尽可能使用props的状况下,代码可预测性很强。

组件开发

  1. react认为组件就是一个状态集,尽量使得组件只拥有props。
  2. 当组件须要有本身的处理逻辑时须要用到state,好比控制input的value,弹出层自动隐藏、显示的逻辑等等。
  3. state并不会随着porps的更新而改变,所以在使用 state 时必定要注意是否有 componentWillReceiveProps。
  4. 业务代码为了方便以及速度能够不写 PropTypes,可是可复用的组件使用 PropTypes 来保证组件的正常运行是必要的,组件中的工具方法能够抽取出来写测试用例。

setState

state为key-value的集合,通常来讲value都是基本类型,当state的数据结构层次很深的时候,操做state就会变成很头疼的事情。前后端分离

深拷贝

// shallow copy
var state = deepCopy(this.state);
state.valueWantChange = vale;
this.setState(state);

深拷贝方法没有问题,但因为deepCopy效率很低,通常都不推荐使用。

forceUpdate

this.state.valueWantChange = vale;
this.forceUpdate(); // this.setState(this.state);

在如下两种状况会用到 forceUpdate

  • 手动更改了 state 以后须要触发 render
  • 作了除更改props和state以外的操做后,须要render。

可是使用forceUpdate 会跳过 shouldComponentUpdate 的过程,会触发子组件的全部lifeCycle方法(包括shouldComponentUpdate)从而形成性能的浪费。所以为了组件更加清晰高效,应该避免使用forceUpdate。

Immutability Helpers

我推荐使用React.addons来管理state
You can alleviate this by only copying objects that need to be changed and by reusing the objects that haven't changed.

import react from 'react/addons'
var newData = React.addons.update(myData, {
  x: {y: {z: {$set: 7}}},
  a: {b: {$push: [9]}}
});
this.setState(newData);

下面是update的基本语法。若是用过mongo应该对此十分熟悉。

  • {$push: array} push() all the items in array on the target.
  • {$unshift: array} unshift() all the items in array on the target.
  • {$splice: array of arrays} for each item in arrays call splice() on the target with the parameters provided by the item.
  • {$set: any} replace the target entirely.
  • {$merge: object} merge the keys of object with the target.
  • {$apply: function} passes in the current value to the function and updates it with the new returned value.
相关文章
相关标签/搜索