iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 23
0
自我挑戰組

React 30 天學習歷程系列 第 23

【Day 23】React 的高級特性

  • 分享至 

  • xImage
  •  

Reac.memo

React.memo 是一個高階組件,主要用於優化性能,跟 PureComponent 類似,差別在於 PureComponent 是用於包裝 class component,memo 是用於包裝 function component。它主要的功能是去比較 props的變化,如果父元件傳入子元件的props 沒有變化,memo 就不會重新渲染,而是使用上一次的渲染結果。
memo 的使用方式也很簡單,只要調用 React.memo 並把元件傳進去就可以,就像下面的範例

const UserProfile = React.memo((props) => {
    const { data } = this.props 
    return <div>
           { data }
    </div>
})

利用 memo 自定義比較函式

memo 也可以自定義比較函式,下面的例子,我們自定義一個 isEqual 函式,它會傳進舊和新的 props 並且比較是否不同,如果不同就返回 false,元件就會重新渲染。

const UserProfile = (props) => {
    const { data } = this.props 
    return <div>
           { data }
    </div>
}

// 比較函式
const isEqual = (prevProps, nextProps) => {
    if (prevProps !== nextProps) {
        return false
    }
}

export default React.memo(UserProfile, isEqual)

Code Splitting (程式碼分割)

大多數的 React 專案都會透過 Webpack 之類的工具打包,將所有檔案合併成一個可以被網頁載入的檔案。但是當專案越來越大,使用許多第三方套件時,打包後的檔案也會很大,導致網頁初次渲染時很慢,這時候就需要 Code-splitting,讓我們只加載當前頁面需要的程式碼。它的原理是將專案打包成多個檔案,避免使用者載入目前不須使用的程式碼,減少初次載入的時間。

動態 import()

動態 import() 是 ES6 新增的語法,是實現 Code Splitting 的基礎,它和我們平常直接使用 import 的方式不同,並不是返回一個元件,而是返回一個 Promise,因此必須再用其他的方式去取得資料,例如 React 內建處理的 React.lazy 或是像第三方套件 loadable-components 都可以處理。

以下面的程式碼為例,Webpack 在讀取到這種程式碼時候,就會自動啟動 code-splitting,不過需要在 Webpack 中去做一些 Code Splitting 的設定

// 一般 import
import { add } from './math';
console.log(add(16, 26));

// 動態 import
import("./math").then(math => {
  console.log(math.add(16, 26));
});

如果是使用 create-react-app 或 Next.js 的話,本身就內建支援 Code Splitting 了,以下面圖的為例,是我們在之前個人履歷網頁練習的專案,經過打包之後,我們可以看 build 資料夾底下, static 內的 js 資料夾,裡面分成很多支檔案,這就是 Code Splitting 分割後的結果。

React.lazy

React.lazy 讓我們可以 render 一個動態 import 的元件,它的使用方式很簡單,在裡面傳入一個回調函式,返回值就是前面提到的動態 import,透過這個方式,將其轉為正常的元件,讓我們可以調用。

import UserData from './UserData';
// 利用 React.lazy 轉化動態 import 的 UserData 元件
const UserData = React.lazy(() => import('./UserData'));

// 調用 UserData 元件
const UserProfile = () => {
    return <div>
        <UserData />
    </div>
}

React.Suspense

lazy component 必須在 Suspense component 內 render,否則會報錯,React.Suspense 主要有以下幾個功能

  • 配合渲染 lazy component,實現程式碼分離。
  • 在 lazy component 加載時,顯示一些 fallback,像是 loading。
    使用 React.Suspense 的方式也很簡單,只要直接調用 Suspense component,並將 lazy component 放進去就可以了,只是 Suspense 裡面必須有一個 fallback 屬性,放入加載時的元件或 JSX,如下面範例中的 <div>loading...</div>
import UserData from './UserData';
// 利用 React.lazy 轉化動態 import 的 UserData 元件
const UserData = React.lazy(() => import('./UserData'));

// 調用 UserData 元件
const UserProfile = () => {
    return <div>
        <React.Suspense fallback={ <div>loading...</div> }>
            <UserData />
        </React.Suspense>
    </div>
}

React.lazyReact.Suspense 目前還不支持服務端渲染,如果是使用服務端渲染,可以使用前面提到的第三方套件 loadable-components 處理。

小結

從這篇可以看出來 React 的高級性能主要都是在優化效能,memo 起到了在渲染時優化的功用,而 React.lazyReact.Suspense 讓我們可以在 React 中實行程式碼分離,讓專案在網頁上渲染時能更有效率的載入。


上一篇
【Day 22】遠端資料請求方式以及 API 統一管理
下一篇
【Day 24】React Hook(一): Hook 簡介 及 useState、useEffect 使用
系列文
React 30 天學習歷程30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言