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…

相關文章
相關標籤/搜索