首先,本文会是一个相对长期的工作。目前还不确定将来是修改增幅,还是分一二三。
先进入正题。
关于React的hook api
react的component和function组件的设计是非常有趣的。我在前端框架的发展过程中,我们发现似乎生命周期越来越不被大家青睐。而面向过程还是面向对象,在react这一点的设计上尤其有着的借鉴意义。
生命周期,显然是一个面向对象的设计。它将流程结构化,成为组件的一部分。而function组件,这种函数式的设计,描述的与其说是一个组件,不如说定义了一个组件的渲染规则——你看到的JSX就像是作文的格式。
这一点在Hook没有出现之前其实非常让人困扰。因为这很JS——你面临的困境和搞面向对象的人第一次写JS是一样的,毕竟JS有最富有魅力的闭包和其次有魅力的异步(我瞎说的)。
当你使用函数式组件时,一旦你需要将开发中大量需要复用的UI抽象成组件时,困难就来了,因为这是前端——这玩意讲究交互。你有很多数据要改变,有很多状态要切换,有很多参数要传。而不可变的props让人绝望,我们的function需要某种机制来描述这些与纯洁的函数无关的副作用——这也是过程和函数的区别。
副作用
数据获取,设置订阅以及手动更改 React 组件中的 DOM 都属于副作用
是的,我们最早的可行方案是用React.Component。
没错这是一个非常有效的方案,并且成功的让我们从过程中逃脱了出来,能够拥抱对象了。什么过程,什么渲染前,什么API,都请在对象树里找到自己的树墩。但是用组件对象的思维在前端开发中同样会遇到一个问题,跨组件传参等行为的复杂度会因为项目的复杂度指数级提升,尤其是多人协同的时候,你会由衷的爱戴彻底的面向对象和面向接口。这一点和vue很类似,当然我们有了redux/dva/vuex等等来解决这个问题,我们有各种各样的神奇方案。但是总有那么点别扭不是吗?因为组件的解耦需要我们将组件优雅的分离,而交互带来的各种数据穿插会扭曲你的姿势。
因为交互就是这么个东西,它比对象高一维,它描述的是组件的变化。而这时我们拥有另一个宝具——Hook API。很多使用vue和react component的朋友理解hook会遇到困难,事实上很多时候react hook难以理解的地方,来源于我们描述的其实是一个组件渲染的过程,但是“组件”的概念很容易让人当成一个组件对象。如果你以对象的角度去思考,这种心智模型会将人带入一个死胡同,你没办法真正的解决副作用。
虽然看上去Hook同样也是为了实现某种机制来描述交互带来的副作用而选择的不得已的手段,但是它与众不同的一点是你在用逐帧的角度去思考交互。相信我,一旦习惯使用Hook你会获得另一个维度的视角,你会掌握交互——真正的感受到闭包的力量,虽然很难以理解,但这就是真相。
useEffect 在渲染结束时执行,所以不会阻塞浏览器渲染进程,所以使用 Function Component 写的项目一般都拥有更好的性能。
所以这里没有useState,useEffect的用法和注意事项,也没有各种需求的解法(这些都可以在下文中更专业的参考文档中找到)。我觉得首先可以理解的是函数式组件是一个渲染过程,而component是函数的一层壳。而当你使用hook,我们就放弃了对象的壳,要从一次次渲染过程的角度去理解它。
相信带着这种思维,理解它会变的轻松许多。
然后推荐一些很实用的HOOK文章。
参考文档:
Hook API 索引
https://zh-hans.reactjs.org/docs/hooks-reference.html
使用HOOK请求数据
https://www.robinwieruch.de/react-hooks-fetch-data
useEffect 完整指南
https://overreacted.io/zh-hans/a-complete-guide-to-useeffect/
其他:关于前端
通常意义上,我们把网站前台的开发工作集合叫做前端,这包括PC,移动端等的web网页工作。事实上,前端与大多数开发工作都有些区别。在我看来,前端的UI交互是让它最与众不同的地方——同样很多时候也是最痛苦的地方。
这里我们抛却设计层面和视觉结构方面的东西不谈,在逻辑上,前端要解决的不只是数据流的IO,还要同步去实现交互动作——也就是解决UI的IO工作。而这种并行的IO,同样也是很多前端从业者抱怨难以协同,代码结构多样的核心原因。类似的工作在客户端,APP,小程序,游戏开发中都有遇到。
这里我们先不谈版本迭代中产品构思不周导致的架构性问题,也不考虑需求调整中导致的各种冲突,只从前端工作本身的矛盾中去寻找一些契机。
前端是与人直接打交道的环节,很多需求往往还没有进入抽象阶段。我们可以想象前端与后端有一条通道,提供了一条前端与持久化沟通的IO渠道。前端与用户之间通过IO设备,提供了一条与用户行为沟通的IO通道。
而时下两大前端框架,就在这两个核心点上有了哲学上的区分。
React以交互为核心,我们要思考的是用户的因和果。用户操作前的动作是什么样,操作后的结果是什么样。由UI和行为指导并驱动着整个开发过程,而数据是在此基础上的配合建筑。Vue以数据为核心,思考的是数据的流向,将每一个组件抽象成数据模型,而UI和动作很多是自动化的点缀工作。
当然这样描述可能会有失偏颇,因为实际使用中很多人会发现react和vue有着很多相似或者与理念相悖的设计。这也是框架与设计模式本质的区别,前者终究追求实用,而后者需要带给设计者以灵魂。