Silencer-1984 / Summary-of-front-end-work

总结包括一切关于前端学习的东西,面试、学英语、开发规范
0 stars 0 forks source link

react #23

Open Silencer-1984 opened 3 years ago

Silencer-1984 commented 3 years ago

生命周期

react-version-16 3-after

React 逐渐废弃的生命周期方法:

挂载阶段

存在以下问题:

更新阶段

卸载阶段

调用 setState 之后发生了什么

setState 是同步还是异步

有时候同步,有时候异步。

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

组件通讯

Hook

Hook 使用带来的好处:

性能优化

  1. 首屏渲染优化。
    SVG
    ,也可以使用插件 prerender-spa-plugin 插件进行首屏渲染。
  2. 页面切换优化。使用 html-webpack-plugin 插件自动插入 loading,这样切换的时候,就不需要在每个页面都写一套 loading。
  3. 减少业务代码体积。通过 Tree Shaking 来减少一些代码。
  4. 提取公共代码。通过 SplitChunkPlugin 自动拆分业务基础库,减少大文件的存在。
  5. 切分代码。通过 Code Splitting 来懒加载代码,提高用户的加载体验。例如通过 React Loadable 来将组件改写成支持动态 import 的形式。
  6. 懒加载。React 可以通过 react-lazyload 这种成熟组件来进行懒加载的支持。
  7. 页面占位。有时候加载页面的文本、图片的时候,会出现 “闪屏” 的情况,比如图片或者文字没有加载完毕,对应位置空白,然后加载完毕,会突然撑开页面,导致闪屏。这时候使用第三方组件 react-placeholder 可以解决这种情况

事件机制

React 其实自己实现了一套事件机制,首先我们考虑一下以下代码:

const Test = ({ list, handleClick }) => ({
    list.map((item, index) => (
        <span onClick={handleClick} key={index}>{index}</span>
    ))
})

以上类似代码想必大家经常会写到,但是你是否考虑过点击事件是否绑定在了每一个标签上?事实当然不是,JSX 上写的事件并没有绑定在对应的真实 DOM 上,而是通过事件代理的方式,将所有的事件都统一绑定在了 document 上。这样的方式不仅减少了内存消耗,还能在组件挂载销毁时统一订阅和移除事件。

另外冒泡到 document 上的事件也不是原生浏览器事件,而是 React 自己实现的合成事件(SyntheticEvent)。因此我们如果不想要事件冒泡的话,调用 event.stopPropagation 是无效的,而应该调用 event.preventDefault。

那么实现合成事件的目的是什么呢?总的来说在我看来好处有两点,分别是:

合成事件首先抹平了浏览器之间的兼容问题,另外这是一个跨浏览器原生事件包装器,赋予了跨浏览器开发的能力 对于原生浏览器事件来说,浏览器会给监听器创建一个事件对象。如果你有很多的事件监听,那么就需要分配很多的事件对象,造成高额的内存分配问题。但是对于合成事件来说,有一个事件池专门来管理它们的创建和销毁,当事件需要被使用时,就会从池子中复用对象,事件回调结束后,就会销毁事件对象上的属性,从而便于下次复用事件对象。