class已被淘汰,React 要推行函数式组件,心智模型更加“函数式”

class已经淘汰了?React 现在要推行函数式组件,你的观点呢?

一些同学可能认为“函数式组件+useState”不就是有状态了吗,不就是class组件的另一种写法吗?只不过更优雅一些?

我认为fb团队花那么大的力气,拽着整个React社区往一个前所未有的方向前进,原因肯定不仅仅是“写法更优雅”。真正的原因如下:

1.hooks是比HOC和render props更优雅的逻辑复用方式。

这个是很多人喊“真香”的原因。优雅的逻辑复用方式,会促进一个更加蓬勃的生态,这对于原本生态就很强的react相当于如虎添翼。会有更多的人愿意把自己的逻辑抽离成hooks(因为真的太优雅了),发布为library,为react生态添砖加瓦(看看这段时间各种基于hooks的状态管理工具)。我还预测,很快会出现几个“hooks圈子”的“lodash”。

class已经淘汰了?React 现在要推行函数式组件,你的观点呢?

2.函数式组件的心智模型更加“声明式”。

hooks(主要是useEffect)取代了生命周期的概念(减少API),让开发者的代码更加“声明化”:

  • 旧的思维:“我在这个生命周期要检查props.A和state.B(props和state),如果改变的话就触发xxx副作用”。这种思维在后续修改逻辑的时候很容易漏掉检查项,造成bug。
  • 新的思维:“我的组件有xxx这个副作用,这个副作用依赖的数据是props.A和state.B”。从过去的 命令式 转变成了 声明式 编程。
  • 其实仔细想一想,人们过去使用生命周期不就是为了判断是否要执行副作用吗? 现在hooks直接给你一个声明副作用的API,使得生命周期变成了一个“底层概念”,无需开发者考虑。开发者工作在更高的抽象层次上了。
  • 类似的道理,除了声明副作用的API,react还提供了声明“复杂计算”的API(useMemo),取代了过去“在生命周期做dirty检查,将计算结果缓存在state里”的做法。

class已经淘汰了?React 现在要推行函数式组件,你的观点呢?

3. 函数式组件的心智模型更加“函数式”。

react团队正在循序渐进地教育社区,为未来的并发模式打下基础。(其实react从一开始就受到了很多函数式编程的影响,现在推行函数式组件算是“回归初心”)。下面我会详细讨论函数式组件的心智模型。

扫描二维码关注公众号,回复: 11134560 查看本文章

函数式组件的心智模型

函数式组件绝不仅仅是“另一种写法的class组件”,它和class的组件在心智模型还是存在很大差别的。 函数式组件依然是【外部数据=>view】的映射,依然是pure function的心智模型。 只不过现在外部数据不仅仅包括props和context,还包括state。

事实上,未来的并发模式就要求你使用pure function的心智模型来编写函数式组件,否则很容易出bug。

class已经淘汰了?React 现在要推行函数式组件,你的观点呢?

state是一种外部数据

有同学可能会问:“你在逗我吧?都useState了你还pure呐???”

但是你发现没有,react对hooks的种种限制,不就是为了让你把useState等hooks 声明 在函数组件的开头?(当然,提高hooks的性能也是很重要的一个原因)并且,useState状态声明是 静态声明 ,不会因为【props这种运行时因素】的变化而改变。你完全能写个代码分析工具,无需构建运行就能收集所有状态声明。

静态声明一个state,不就相当于用一个Wrapper组件来持有这个状态,然后传给它?那这个state不就可以理解为一种外部输入? 举个例子:

// MyComp看起来好像有状态,不是纯函数 :( 
function MyComp() {
  const [state, setState] = useState(0)
  return <div>{state}</div>
}

相当于

// MyComp现在看起来更像一个纯函数了吧!
function MyComp({state, setState}) {
  return <div>{state}</div>
}

function WrappedMyComp() {
  const [state, setState] = useState(0)
  return <MyComp state={state} setState={setState} />
}

后者看起来更像是在写纯函数了吧,但是两者其实是等价的啊!那么useState是不是就可以看作是一种语法糖,用来声明它的Wrapper应该持有哪些状态!只不过useState会自动帮你生成这些Wrapper。

这里只是讲心智模型,内部实现肯定会更加高效。

class已经淘汰了?React 现在要推行函数式组件,你的观点呢?

事实上,hooks的前身,recompose 就提供了用来声明状态的HOC(`withState`),用它来包裹函数式组件以后,函数式组件就像自己拥有了state一样。

综上所述,useState得到的状态可以理解为一种外部传入的状态,就像props、context一样。hooks时代的函数式组件依然是【外部数据=>view】的纯函数。

这对于开启并发模式是必备的条件。在并发模式下,react可以同时渲染“多个版本”的组件树(比如,在渲染阶段,一个优先级更高的事件发生了,要用这个事件改变的状态进行新的渲染),对于某个版本,useState返回某个状态值,对于另一个版本,useState返回不同的状态值。react开发者只需要编写纯函数,不需要关心如何应对这些并发渲染。

而如果你用了class组件,就很容易出问题,因为“多个版本”的组件树,其中的class实例是共享的,你在某个组件树中修改了this.A,其他组件树能够感知到。useRef也是同理,ref会造成组件树之间相互影响,它是react团队开的后门,建议谨慎使用。

发布了24 篇原创文章 · 获赞 0 · 访问量 1901

猜你喜欢

转载自blog.csdn.net/lishuo2039/article/details/105587508