React项目组件继承实战

囿于reat使用组合而不是继承的提示,大家似乎都不怎么使用继承,然而在一些方面继承还是能发挥不少作用。

为什么使用继承

当我们有多个页面需要执行页面初始化操作,可能是动态计算视口的宽高度、计算屏幕的分辨率,甚至为一些节点添加初始化的事件(注意页面卸载时注销),或者一些其他的http请求、验证等初始化行为。这些行为有一个特点:需要重复执行或某一时间后重复执行。继承实现了代码的共享与复用

执行顺序:

  • 构造函数执行:先执行继承员最上层组件的构造器,紧接一层,再紧接,最后到达末代的构造器
  • 生命周期(componentDidMount):先最内层的组件,紧接的外层,最后最外层。
  • 类似于函数的开栈与闭栈

我的实现过程

下文中的page组件指单个页面的最上层组件。

鄙人使用继承的初衷是想实现一种数据的共享,取代react-redux的繁琐。比如我在最高层的组件(祖先组件,所有的组价都继承于此,该组件又继承自React.Component)的构造器里设置一个Ready变量,并传递给继承组件,该变量是一个promise,返回内容是用户相关的数据,这样所有的继承组件都继承了该promise,并在声明周期钩子里通过then调用待数据请求到了以后再做相应的依赖请求。

听起来不错,哈,然而现实是残酷的。

由于祖先组件本意是被多个组件继承的,因此我在其他地方也继承该组件,就导致了constructor的多次调用(直接造成了重复的http请求),还不包括继承该组件的其他page,唉!

于是,我想到了缓存:

  • 使用localStorage,没错,但是没有失效时间,虽然可以在logout时代码清楚,但是用户直接关闭浏览器并重新登录呢(假设登录与用户信息相互独立)?
  • sessionStorage,这个可以避免上述问题,自动失效。
  • cookie,比较复杂,且api不友好,但可以自由设置生效时间.

综上,选择了sessionStorage.
每次调用前先判断本地是否有缓存,没有才请求。
然而http请求是异步的,在首次请求完成并写入缓存之前可能已经执行缓存检查并发出第二个请求了,所以重复请求的问题并没有解决

继续思考:
如果我们只在page组件(多个组件的组装产物)实现继承,那么问题是可以解决的。再将需要继承的属性通过props传递到下层组件。

再次思考:
可能有些东西我们是需要page组件每次加载都执行的:

  • 为所有页面上的DOM节点注册事件
  • 计算屏幕的分辨率,并据此实施字号大小(rem布局)

我们可以将这些 高频的初始化逻辑放到祖先组件的componentWillMount里执行,因此此时,子组件都mount完毕了。可以访问到节点信息。
而那些用户信息、验证信息,可能在一段时间内只需要执行一次,我们采用sessionStorage缓存。这样页面跳转时(一般用户会停留一段时间才会跳转页面)就能做缓存判断了。

有些page组件做验证,有些可能做信息获取,这些都是页面正常展示的基础,有必要写几个不同的祖先组件,分别实现不同的初始化逻辑:这样既实现了无关代码与业务代码的分离,划清了界限,也细分了类别,提升扩展性

总结一下就是:
只在page组件实现继承
实现不同的继承组件源
使用cookie、sessionStorage实现缓存

真能代替redux?

继承实现了上层组件共享同一个代码片段并将结果传递到子组件的过程。

redux解决的是组件之间交互的问题,具有自动追踪更新的功能,就像页面之间共享的state一样。

两者做的事情截然不同,当然不能代替。

组件之间为何需要通讯state

为啥会有共享state这一说?
为了实现复用将一个大功能切割成一个个小逻辑单元,虽然看起来简洁了,但是彼此之间通讯也被关闭了,因此有了状态提升Lifting State Up),状态提升意味着高层组件过多的逻辑,我们不想让代码变得晦涩难懂,于是采用redux是顺其自然的事。

总结

啥时候使用redux?

  • 当页面有多个频繁改变的状态分属不同的组件(尤其是表单
  • 某一处需要收集所有的状态,并做相关处理
  • 不方便状态提升

page组件层进行store的初始化。


本文完,欢迎志同道合的小伙伴留言或评论哦!

你可能感兴趣的:(前端开发,架构设计)