iT邦幫忙

2021 iThome 鐵人賽

0
自我挑戰組

Be friend with JavaScript系列 第 38

React Hooks - useContext

當我們要將父元素的資料傳遞到子元件的時候會使用 props,但假設有很多個 component,曾曾曾祖父元件要傳遞 props 給子元件的話,要把 props 每層一直傳下去,儘管某些 component 根本不會用到這個資料卻也要幫忙傳,這樣複雜又麻煩的傳遞方式會讓程式碼變得很大,也很容易出現錯誤訊息,為了解決這問題,我們可以使用 useContext Hook(如果程式更大可以用 Redux)。

useContext 在 React 中為全域,能在多個 component 間跨組件共享資料,例如:主題深淺色模式、註冊及登入的 Token,或是用戶資料等,通常用在不常需要被變動的值或多個不同層級的元件間的傳遞,如果不是的話,使用 props 傳遞就好,因為當 context 更新時所有有用到 useContext 的 component 都會重新 render,過度使用的話會讓效能變得很差。

使用方式:

  • import createContext 並創造 createContext(),被創造出來後,會 return 一個裡面有 Consumer 和 Provider 的 context object。
import React,{ createContext } from 'react'
const dataProvider = createContext();
console.log(dataProvider);

https://ithelp.ithome.com.tw/upload/images/20211008/20140282CjZb4xQFH3.jpg

  • 傳遞資料時使用 Context.Provider 包住,並在 provider 中放入需要傳遞的 props value
// 引入 createContext
import { createContext } from 'react';
// 創造 context object
export const xxxContext = createContext();
// 渲染子元件時外面用一對 Context.Provider 包住,並透過 value 屬性傳遞給後代元件
export const DataProvider = () => {
    return(
        <xxxContext.Provider value={ zzz }>
            // 需要 context object 的 component
        </xxxContext.Provider>
    )
}
  • 接收資料時使用 Context.Consumer 包住,但在 function component 內使用 useContext() 即可取得 context object。
// 引入 useContext
import { useContext } from 'react';
// 拿已創造完成的 context object 來做使用
import { xxxContext } form './DataProvider.js'
// 執行 useContext(),接收由 createContext 回傳的 context object,回傳該 context 目前的值
const yyy = useContext(xxxContext);

例如:

// 引入 createContext 和 useContext
import { createContext,useContext } from "react";
// 創造 Context object
const UserContext = createContext();
// 使用 Provider 傳遞 value 給 User
export default function App() {
  return (
    <UserContext.Provider value="Hello">
      <User />
    </UserContext.Provider>
  );
}
// User 使用 useContext() 接收來自 UserContext 的資料
function User() {
  const value = useContext(UserContext);
  return <h1>{value}</h1>;
}

此時可以看到網頁上顯示 Hello


上一篇
React Hooks - useRef
下一篇
React Router
系列文
Be friend with JavaScript39

尚未有邦友留言

立即登入留言