学习记录

123 阅读3分钟

hooks 里面的 useState,useEffect,useMemo的用法

props 变了会触发组件重新渲染,但有的时候 props 并不需要变化却每次都变,这样就可以通过 useMemo 来避免它没必要的变化了 再看几个别的 hook,比如 useMemo,它是当依赖不变的时候始终返回之前创建的对象,当依赖变了才重新创建。

一般是用在 props 上,因为组件只要 props 变了就会重新渲染,用 useMemo 可以避免没必要的 props 变化。 useCallback 也是同样的道理

小结一下:

useState 同样分为 mountState 和 updateState 两个阶段

mountState 会返回 state 和 dispatch 函数,dispatch 函数里会记录更新到 hook.queue,然后标记当前 fiber 到根 fiber 的 lane 需要更新,之后调度下次渲染。

再次渲染的时候会执行 updateState,会取出 hook.queue,根据优先级确定最终的 state 返回,这样渲染出的就是最新的结果。

总结

react 渲染流程分为 render 和 commit 阶段。

render 阶段执行 vdom 转 fiber 的 reconcile,commit 阶段更新 dom,执行 effect 等副作用逻辑。

commit 阶段分为 before mutation、mutation、layout 3 个小阶段。

hook 的数据就是保存在 fiber.memoizedState 的链表上的,每个 hook 对应一个链表节点。

hook 的执行分为 mountXxx 和 updateXxx 两个阶段,第一次会走 mountXxx,创建 hook 链表,之后执行 updateXxx。

我们看了 useRef、useMemo、useCallback 的实现原理,这几个 hook 都比较简单。其中后两个 hook 是作为 props 时为了减少不必要渲染的时候用的。

useState 和 useEffect 就和渲染流程有关了:

useEffect 在 render 阶段会把 effect 放到 fiber.updateQueue 的环形链表上,然后在 commit 阶段遍历所有 fiber 的 updateQueue,取出 effect 异步执行。

useLayoutEffect 和 useEffect 差不多,只是 effect 链表是在 layout 阶段同步执行的。

useState 的 mountState 阶段返回的 setXxx 是绑定了几个参数的 dispatch 函数。执行它会创建 hook.queue 记录更新,然后标记从当前到根节点的 fiber 的 lanes 和 childLanes 需要更新,然后调度下次渲染。

下次渲染执行到 updateState 阶段会取出 hook.queue,根据优先级确定最终的 state,最后返回来渲染。

这样就实现了 state 的更新和重新渲染。

这就是 react hooks 特别是 useState 和 useEffect 的实现原理。理解它们不单单要理解 hook 的存储结构,还要理解 react 的整个渲染流程。

微前端

qiankun 是主流的微前端方案,其他的还有京东的 micro-app、腾讯的 wujie 等。

qiankun、wujie、micro-app 的区别主要还是实现容器(或者叫沙箱)上有区别,比如 qiankun 是 function + proxy + with,micro-app 是 web components,而 wujie 是 web components 和 iframe。

微前端就是可以一个页面跑多个 vue、react 甚至 jquery 等不同项目,它之间的 JS、CSS 相互隔离运行,不会相互影响,但也有通信机制可以通信。

实现原理:当路由切换的时候,去下载对应应用的代码,然后跑在容器里。

single-spa,它做的就是监听路由变化,路由切换的时候加载、卸载注册的应用的代码。

微前端方案的功能就那一句话:当路由切换的时候,去下载对应应用的代码,然后跑在容器里。只不过这个容器的实现方案有差异。