3. Why Immutable / 为毛要不可变

最后更新于:2022-04-01 05:02:02

Immutable 是函数式的概念之一,一旦创建出来之后,就不能再改变。因此,当你想对其做修改,就得弄一个新的。 ![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-11-20_564e9932e7227.gif) 好奇的同学要问了,但是 React 看起来是面向对象的啊。 `createClass` , `state` ,函数式有状态和 class 吗? > If a tree falls in a forest and no one is around to hear it, does it make a sound? [2](http://blog.oyanglul.us/javascript/react-cookbook-mini.html#fn.2) 首先,函数式和面向对象并不冲突,两种编程范式分别有各自的方式解决问题。 其次: ## 3.1 状态 如果状态只存在于 Component 中又并没有影响任何人,它还是状态吗? ClojureScript 的 React 库 om,只有一个 app 级别的 state。因此所有的 component,其实并无状态。 [https://youtu.be/5yHFTN-_mOo](https://youtu.be/5yHFTN-_mOo) ## 3.2 Class 想象一下使用一个 React Component 的时候 ~~~ <AFancyHelloWord message="Good News Everyone!"/> ~~~ 来想象一下 1. 尖括号 `<` 往右移 2. 尖括号变成圆括号 3. 里面再加个大括号 4. 等号变冒号 ~~~ AFancyHelloWord({message:"Good News Everyone!"}) ~~~ [./images/futurama_August_26__2015_at_0617AM.gif ](http://blog.oyanglul.us/javascript/images/futurama_August_26__2015_at_0617AM.gif)ok, 如果把每个 Component 看成一个函数,为了我们的代码更好 reason about 而且更 loose couple,我们应该尽量要**消除** 每一个 Component 的状态。 这样在 Component 的树中,我们可以随意切换 Component,以 Star Wars 为例,Anakin 有两样东西,Luke 和光剑: ![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-11-20_564e993329b5a.png) 当 Anakin 变成 Darth Vader,光剑的颜色变红时,Darth Vadar 有 Luke 和 红色光剑。 ![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2015-11-20_564e993337585.png) 实际上我们需要尽量减少 Component 中的状态,而且对着少数的状态,由于他们是我们的 source of truth,并不希望他是 mutable 的,这样我很难知道谁动了我的 source of truth。 ## 3.3 让你的数据结构 immutable 的工具们 ### [Immutablility helper](http://facebook.github.io/react/docs/update.html) 这是 react addon 中自带的工具,如果你并不想完整的 Immutable 数据结构,这个工具可以帮助 copy 一份来做改动 ~~~ var update = require('react-addons-update'); var inc = x=>x+1 var fancyPropsForChild=update(this.state, { x: {y: {z: {$set: 7}}}, a: {b: {$push: [9]}}, h: {$merge: {i: "j"}}, e: {$apply: inc} }); ~~~ ### [mori](https://github.com/swannodette/mori) 更为彻底的选择是,使用 ClojureScript 的 Immutable 数据结构。benchmark 要比 facebook 的 Immutable.js 好上许多,但是使用上跟 ClojureScript 一致, 用惯JavaScript的人可能不太能习惯,alternative 是使用我 fork 的 mori 版本[conjs](http://github.com/jcouyang/conjs)。 ### [Immutable.js](https://facebook.github.io/immutable-js/) facebook 实现的 immutable 数据结构,使用上比较符合 JavaScript 习惯一些, 不过跑分低一些。
';