React 17 更新了什么

支持混用

react 17 最主要的改动仍然是要支持渐进式,你能够在一个应用中使用 react17,另一个使用 react 18。html

const rootNode = document.getElementById('root');
ReactDOM.render(<AppReact17 />, rootNode);

const rootNode2 = document.getElementById('root2');
ReactDOM.render(<AppReact18 />, rootNode);
复制代码

react 官方要支持这种用法,推测的 react18 的改动将会巨大无比,甚至于彻底不兼容旧的。前端

更改事件委托

原来的 react 的事件系统是挂在 document 上的,为了支持混用将会修改到你挂载的 rootNode 中,这样其实会形成一些问题,好比说原来的 e.stopPropagation() 能解除原生 document 事件的冒泡,如今只能阻止到 rootNode,但大部分时候是没有影响的。react

image.png

portals 的事件还会继续监听,固然还有一些小更新git

  • onScroll事件再也不冒泡,以防止出现一些混淆
  • React的onFocus和onBlur事件已在底层切换为原生的focusin和focusout事件。它们更接近React现有行为,有时还会提供额外的信息。
  • 捕获事件(例如,onClickCapture)如今使用的是实际浏览器中的捕获监听器
  • 去除事件池,在如今浏览器上,这个功能不会提高性能,反而会由于重用事件对象,形成困扰。
  • focus 事件底层切换成了 focusin,行为没有变化。

整体而言,此次改动会让 react 的事件树更符合 dom 的规范,虽然会致使不少面试题不能用了。github

useEffect 的回调修改成异步调用

useEffect 的反作用清理函数是在 effect 执行以后立马执行的,可是在使用中发现了若是回调中的操做比较耗时,会形成一些性能问题,如今useEffect 的 反作用清理函数会在 render 后执行了。面试

官方提供了一个 demo 来展现可能会形成的问题,咱们通常也不这么用。若是有特殊状况,能够用 useLayoutEffect 来代替。typescript

useEffect(() => {
  const instance = someRef.current;
  instance.someSetupMethod();
  return () => {
    instance.someCleanupMethod();
  };
});
复制代码

返回一致的undefined错误

这个改动几乎无感,之前,React只对class和函数组件执行此操做,但并不会检查forwardRef和memo组件的返回值。如今都会检查,不要写奇怪的代码是不会挂的。最好用 return null 来代替。数组

展望一下 18

自从 2016 年 Seb 提出了 fiber 架构以来,react 已经吊足了人们的胃口 4 年了。react16 重写了 react 的渲染引擎,一直到最近发布的 17,看起来 async component 终于快要发布了。这几年虽然有了 hooks,可是仍然没有 fiber 来的让人激动。浏览器

fiber 架构主要仍是用来对 cpu 和网络的问题,这两个问题一直也是最影响前端开发体验的地方,一个会形成卡顿,一个会形成白屏。为此 react 为前端引入了两个新概念。markdown

Time Slicing 时间分片

时间分片是利用了 fiber 的可中断,可继续的功能,每一个渲染周期内都会留一部分的时间来响应用户的输入,或者其余 IO 的状态修改。

  • React 在渲染(render)的时候,不会阻塞如今的线程
  • 若是你的设备足够快,你会感受渲染是同步的
  • 若是你设备很是慢,你会感受还算是灵敏的
  • 虽然是异步渲染,可是你将会看到完整的渲染,而不是一个组件一行行的渲染出来
  • 一样书写组件的方式

Suspense

// 这不是一个 Promise。这是一个支持 Suspense 的特殊对象。
const resource = fetchProfileData();


function ProfileDetails() {
  // 尝试读取用户信息,尽管该数据可能还没有加载
  const user = resource.user.read();
  return <h1>{user.name}</h1>;
}

function ProfileTimeline() {
  // 尝试读取博文数据,尽管数据可能未加载完毕
  const posts = resource.posts.read();  return (
    <ul> {posts.map(post => ( <li key={post.id}>{post.text}</li> ))} </ul>
  );
}


function ProfilePage() {
  return (
    <Suspense fallback={<h1>Loading profile...</h1>}> <ProfileDetails /> <Suspense fallback={<h1>Loading posts...</h1>}> <ProfileTimeline /> </Suspense> </Suspense>
  );
}
复制代码

** react 的思路已经拓宽了整个前端的边界,18 发布以后虽然会形成不少问题,好比 antd 的动画就必定会挂。可是默认的性能提高可让不少中后台得到性能加成, 不少项目其实最后也不会有机会进行细致的优化。Suspense 更是会更改咱们前端写代码的范式,期待早点发布。

参考文档

reactjs.org/blog/2020/0… reactjs.org/blog/2018/0… github.com/acdlite/rea… zh-hans.reactjs.org/docs/concur…

相关文章
相关标签/搜索