前端框架的最佳实践(AngularJS 和 React)

对框架的使用者来说,谈一个框架的思想,其实不如谈谈它的最佳实践。就是同一个框架,不同的人实现相同的功能,代码也是千差万别。不同风格的实现自然也有高低之分,而往往这些东西还没有成文的规定,不知道坑了多少前端。这些框架还有另一个特点—–非常容易上手(入坑),从而埋下更深的祸患。这么简单!其实往往是不明所以的时候就开始挖坑了。

2015年初时计划切换框架,因为一直在做的都是管理后台类项目,所以理所当然地投奔到 AngularJS 阵营了。在做切换到 AngularJS 时,需要有一个思维上的转变,原来对 DOM 的操作要转为操作数据,数据发生变化了,界面就会跟着变化。用过 AngularJS 的同学估计都记得一些建议和警告:

  1. 不要使用 jQuery (不合时宜地操作 DOM)
  2. 尽量避免 global scope
  3. 保持瘦 Controller
  4. …(快一年没写了,不记得了–!)

其中一些很容易理解,表示的很清楚,这些还好(表示还是都见到 😞 )。另外一些就很难说了,比如:

  1. ng-init 这个标签,有人不顾警告地使用,我是万万没想到,Controller 初始化的部分逻辑要看模板才知道。
  2. 类似的情况,实现一个 directive 做拉取数据的逻辑。复用代码的方式有很多,何必这样呢?你这样做数据流还怎么管理?告诉我!
  3. 模板里面写很长很长的表达式。对于模板,一定不要做太多事,一定不要写太多逻辑。流过这么多泪之后,个人非常推崇 Logic-less template。后来在 React 中有人吐槽 JSX {} 中不能写 if 语句,只想说你们真没痛过么?

关于 AngularJS 现在想起的也就这么多了,项目搭建好后,后端也能撸代码。不过,你得遵照一点要求:取数据在一层;处理数据在 service;controller 简单的调用函数,挂数据在 scope 上;模板保持简单。后端 MVC 中不是也要 保持瘦 controller 的,逻辑丢在 service 么,你前端写这么乱,感情你后端代码也是一粪池?

最开始接触 React 是在 2015 年,最开始的印象是: JSX 好奇怪,只是做了渲染。今年年初接触 React 时,看到当时项目时,感觉怎么比 AngularJS 还麻烦还难读。当时是纯 React,不难想象到代码结构,一个组件负责一个页面,拉取数据,处理数据,显示对话框,各种逻辑都在里面,数据都在 state 上,一个文件七八百行不成问题。于是想拆,按照 Angular 的思想,取数据和处理数据,总该挪出去吧。可是文件还是很大,于是想找找类似的最佳实践。首先是官网的 thinking in react ,你这是逗我么?这简直是 react hello world

数据流这么乱,先套上 redux 吧(发明 flux 的人一定是被 AngularJS 的数据流搞懵逼过)。在 redux 中倒是有了一点发现,react-redux 入门文档说 深受 分离容器组件和展示组件 思想启发。姑且叫这么个中文名吧。之后翻译了 React.js 初学者应该知道的 9 件事,开始明白纯渲染组件的好处,官网的文章也不是在逗我。 React 开发最佳实践(一句话攻略)就是:写简单可靠的纯组件,然后使用搭积木的方式组合这些小组件搭起一个页面。

之后当有新人要上手做项目时,关于 React,我真不知道要说些什么。那就说说 redux,要怎么写,怎么维护数据流,保证你的组件简单。对于新人来说,上手也确实容易,最开始甚至不需要搞清楚数据流那一套,只需要告诉他怎么写怎么写就可以了。

功能实现很简单,当我看代码时,总是觉得别扭,我不会这么写。第一个问题是,用继承复用相同逻辑,可是如果我来写的话,只会想到组合,因为逻辑相同的是父容器呀。后来,又有同事问可否有多个父类,我很好奇是什么场景,为什么不用组合。因为这么久的项目只有极个别的地方用到了继承。尽量选择组合,官网也是一样的态度,可以看下官网上 组合与继承 最后一段话。Mixins 毫无疑义被 HOC 取代,react-redux 中的 connect 就是 HOC 一例。相关文章 Mixins Are Dead. Long Live Composition (还是他的)

优先组合这个还好说,如何抽象一个组件这个就麻烦了,现实中比较多碰到的是,组件很庞大,越写代码越长,每个组件都尽量拆成纯函数组件不是每个人都能(愿意)做到的。功能都实现了,上线了再说,谁还管这个啊。随便翻翻 github 上的 React 组件库,一个组件几十个属性,代码五百行起的超级组件,你让我怎么看啊!

最后一个小问题也是跟组件抽象有关,没有仔细思考组件的输入和输出。说好听点是封装组件的时候欠斟酌,不好听的话是欠缺抽象封装组件的能力。表象是往往丢给一个组件不需要的属性,或者不需要的多个属性,这个组件其实依赖的是一个处理完成的一个名字,而不是把几个揉在一起。对这类问题,想象一下这个场景,团队中的另外一个人想复用你的组件,你还会暴露这么些属性和方法么?这类问题太常见了,自己调自己的业务组件,想这么多还上线么?

说 React 容易的人,大多是在忽悠人入坑,就像忽悠别人学前端一样。我至今还是不知道怎么教新人写好 React ,这个真心不好教啊。

对于新人,我只能说:前面坑多,少一点浮躁,沉下心来学一段时间再说话。

很早就想写一篇这样的文章,拖了很久,关于 AngularJS 的部分忘太多了。新年第一篇 🎉 🎉 🎉