再论状态——从组件状态到应用程序状态

241 阅读3分钟

现在大家都在关注前端组件状态,也产生了很多前端组件状态的库。不过,状态仅仅是前端组件应该考虑的吗?

这么说吧,前端组件状态,不单是状态管理,同时要考虑组件拆分后状态的传递,及组件随着状态的响应式render,从而导致组件的状态管理必然是复杂的,需要被很好的管理,这没错。

但状态的重要性及其适用领域仅仅是前端组件吗?绝非如此。

个人认为,程序的核心就是状态,编程的核心差异绝非是只是面向对象,还是面向过程或者是否函数式。无论是面向对象,面向过程,还是函数式编程,解决的都只是形式问题,而真正本质的是编写健壮的程序的核心是维护应用程序状态。

函数式编程之所以越来越受欢迎,正是因为其形式部分解决了状态变更不易维护的问题,在这一定上,其远超面向对象的编程。

举例来讲,为何对于应用程序的常量要单独提出来,做为应用的配置文件?原因就在状态。常量其实是应用程序的状态,是应用程序的“变量”,它也经常需要变化,比如对于不同的环境的api base url,不同渠道的page title,必须在配置中进行维护和更改,如果将其放在模块、类、方法(函数)中进行修改,则应用程序的状态变得不可预测和维护。

再举例来讲,模块、类、函数中的变量同样也是其拥有者的状态,因为必须想清楚数据的逻辑,哪些变量应该定义在顶层模块中还是里层函数中,而绝非可以任意为之。同时,无论任何作用域中的变量,都应该定义的越少越好,同时尽可能多的使用不可变数据。正如在Javascript中,越来越多的人已经知道要尽可能使用const,而非let。

在这一点,函数式编程也同样胜出。函数式编程以表达式替代语句,可以很好地避免了定义太多的变量,维护应用程序的不可变性。比如,通过使用pampy提供的模式匹配函数matchPairs,以const a = matchPaires(b, [cond1, result1], [cond2, result2], ...) 替换 let a; if(cond2(b)){ a = 'x' } else if(cond2(b)) { a = 'y' }.... 或 let a; switch(true){ case cond1(b): a = reuslt1, ...} 即可消除了变量的定义,或者ramda提供的ifElse函数也可同样胜任。其他的,还有tryCatch等。此外,函数式编程的柯里化、部分应用、函数组合带来的pointFree风格,可以在函数传递中完全消除变量的使用。

因此,编程的核心就是考虑状态和数据。在任何应用程序中,状态都无处不在,维护好状态才能写出健壮,优雅,可维护的程序。