React基础

79 阅读4分钟

React基础

一、setState的秘密

setState采用异步更新,可以传入回调函数来保证同步更新,也可以用setTimeout

通过事务控制更新队列,那么为什么setTimeout可以实现同步更新呢?(跟vue不同)你真的理解setState吗?

  1. 合成事件中的setState
  2. 钩子函数中的setState
  3. 原生事件中的setState
  4. setTimeout中的setState
  5. setState中的批量更新

总结 :

  1. setState 只在合成事件和钩子函数中是“异步”的,在原生事件和 setTimeout 中都是同步的。

  2. setState的“异步”并不是说内部由异步代码实现, 其实本身执行的过程和代码都是同步的,只是合成事件和钩子函数的调用顺序在更新之前,导致在合成事件和钩子函数中没法立马拿到更新后的值,形式了所谓的“异步”, 当然可以通过第二个参数 setState(partialState, callback) 中的callback拿到更新后的结果。

  3. setState 的批量更新优化也是建立在“异步”(合成事件、钩子函数)之上的,在原生事件和setTimeout 中不会批量更新,在“异步”中如果对同一个值进行多次 setState setState 的批量更新策略会对其进行覆盖,取最后一次的执行,如果是同时 setState 多个不同的值,在更新时会对其进行合并批量更新。

什么是合成事件?

eact为了解决跨平台,兼容性问题,自己封装了一套事件机制,代理了原生的事件,像在jsx中常见的onClickonChange这些都是合成事件。

信息流业务为什么选择React?

技术选型考虑

为什么选择react, 主要是考虑到业务需求,我们M端首页是信息流业务,信息流业务的特点:

  1. 信息流可以抽象成一个双端队列,可以在队列头和尾部插入新内容。
  2. 信息流只负责展示,很少对数据进行修改; 在我们的业务中,只有标记已读和负反馈逻辑。
  3. 信息流逻辑需要输出到微信小程序、m端、直达服务。

这种业务特点决定我们对业务的抽象的结果是:

  • Model层用数组存储信息流,对数组进行unshift 或者push操作表示增加新的feed。
  • View 层对feed数据进行映射,映射成视图。
  • 数据变动的时候,通知view渲染视图。

最终抽象出来一个feed 类

class Feed extends Event{



         feed=[]



         push(){}



         unshift(){}



         read(){}



         dislike(){}



         subscript(){} //如果feed,变更,将feed发送给view 进行render



}

这样feed流的逻辑已经成型,逻辑很干净,只要视图层能够将feed渲染成UI即可,但是在开发直达服务(类Vue的MVVM框架)过程中,我发现VM来托管feed并不合适,有两点无法接受:

1、Vue这种相应式的框架无法跟踪数组的变化,所以对feed流操作必须耦合到vue组件中,包括feed的插入和删除。

2、Vue的响应式原理决定了需要对数组进行递归的依赖收集,feed流这种业务模型,feed流属性众多,数据量大,大多数数据是不会变化的,从feed流中手机依赖会造成内存浪费和性能损失;

3、2的问题导致本来干净的feed流变得冗余,虽然作为开发过程中无法感受到,但是让人很难受。

我们需要一种模型, 仅仅将我们的feed流作为数据源,输出视图,当feed流更新时,输出新的视图。这个模型可以使用以下公式表示:

V = f(D)

V表示视图,D表示数据,我们可以在Feed实例订阅feed的变化,调用f更新视图。这种模型刚好与React 所描述的模型相契合,而且微信小程序因为某些特殊的原因,也选择了类似的思想,这就意味着我们的feed逻辑很容易移植到微信小程序平台, 所以我们好不犹豫的选择了React!

React面试题