iT邦幫忙

2022 iThome 鐵人賽

DAY 12
1

本節大綱

  • 前言
  • React 18 更新總覽
  • 參考資料
  • 結論

前言

React 18 發佈於 2022 年的 3 月,跟 17 的版本發布內容相比較起來,更新的內容是豐富的,而且還兼容之前的版本。

在前幾個月前,如果你說哪是不是,要直接使用 React 18 來開發,我個人建議是可以先觀察個一段時間,不需要急著升級現有應用程式,因為不曉得的是否有隱藏性的問題發生。

然而到了此時此刻 (9 月),React 目前的的版本是 18.2.0,哪也經歷了幾個月市場的實驗及驗證,相信現在直接使用 React 18 的版本,也較無問題產生了。

這裡將介紹 React 18 發佈了什麼更新的內容,並針對這些發布作說明。

React 18 的發佈,可分位以下幾點。

新的工作機制

  • 並行機制:Concurrent

新的 API 及功能

  • 新的渲染應用程式:createRoot
  • 自動批次:Automatic batching
  • 過渡應用程式:Transition
  • Suspense 伺服器宣染:Suspense SSR

React 18 更新總覽

新的渲染應用程式:createRoot

廢話不多說,首先來上張圖片。

createRoot Error

這個錯誤是講在 React 18 已經不支持使用 ReactDOM.render 了,請使用 createRoot 來取代。

目前 (9 月) 在 npm 上的 CRA 安裝版本已經是 18 的版本,因此,在使用 CRA 建立 React 專案時,也改用createRoot 了。

// 之前
import { render } from 'react-dom'

const container = document.getElementById('app')
render(<App tab="home" />, container)

// 修改後 - 一般 React 版本
import { createRoot } from 'react-dom/client'

const root = ReactDOM.createRoot(document.getElementById('root'))
root.render(
  <React.StrictMode>
    <App />
  </React.StrictMode>,
)

// 修改後 - React + TS 版本
import { createRoot } from 'react-dom/client'

// 在特定的 DOM 節點上,創建一個 root 物件
const root = ReactDOM.createRoot(document.getElementById('root') as HTMLElement)

// 可以使用 root 物件來渲染對應的元件,並加上嚴格模式
root.render(
  <React.StrictMode>
    <App />
  </React.StrictMode>,
)

自動批次:Automatic batching

首先舉一個範例:準備中餐。

有批次處理:寫中餐需要的購物清單 => 接著去超市一次性購買 => 開始做飯

沒有批次處理:開始做飯 => 先去買一樣食材 => 回來做飯 => 再去買一樣食材 => 回來繼續做飯 => 如此循環

結論:透過批次處理,可以減少 re-render 的次數。

差異是在 React 18 的版本之前,原本的自動批次功能只會在 React 的事件處理器 (Function) 中。

然而在 promise, setTimeout,原生的事件處理器 (Function) 中或其它事件中,並不會作自動批次。

React 17 與 React 18 (都具有同樣的效果):

以下的 console.log('batchUpdate', count),渲染狀況:

  • 畫面渲染好會印出一次,count 是 0。
  • 當按下 button 按鈕時,會印出一次,count 是 1。
import React, { useState } from 'react'

const Demo1 = () => {
  const [show, setShow] = useState(false)
  const [count, setCount] = useState(0)
  
  const batchUpdate = () => {
    setShow(!show)
    setCount((count) => count + 1)
  }

  console.log('batchUpdate', count)

  return (
    <button onClick={batchUpdate}>Click</button>
  )
}

export default Demo1

哪來個非同步的程式碼,來看結果為何。

useEffect(() => {
  setTimeout(() => {
    batchUpdate()
  }, 2000)
}, [])

以 React 17 的 console.log('batchUpdate', count),渲染狀況來講:

  • 畫面渲染好會印出二次,第一次 count 印出是 0。第二次 count 印出是 1。

以 React 18 的 console.log('batchUpdate', count),渲染狀況來講:

  • 畫面渲染好會印出一次,第一次 count 印出是 0。

透過以上這個範例,在 React 18 之前的版本,如果有多個 state 改變了,哪就會重新渲染該元件多少次。

反之,在 React 18 之後的版本,不管您有多少個 state,都會被合併渲染一次。

在 React 18 也提供了,可以透過手動調整批次處理的 API,來達到我們想要的需求,不過,這屬於進階的部分,這裡就不再多做解說。

參考資料


上一篇
Day 11 | 如何在 Next.js + TS 專案設置 ESLint 和 Prettier
下一篇
Day 13 | React Road Map
系列文
一步一腳印,我的前端工程師修煉30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言