iT邦幫忙

2022 iThome 鐵人賽

DAY 18
4
Software Development

React框架白話文運動系列 第 18

React白話文運動18-React Hook-useContext 02

  • 分享至 

  • xImage
  •  

前言

嗨,我是Hogan
目前在經營自己的自媒體 hogan.tech
主要分享一些有關於程式碼、軟體和科技業經驗分享
有興趣的讀者可以進一步關注我,進而獲得更多資訊唷!

未來文章一併更新於此網站 Hogan.B Lab
並且包含多語系 繁體中文英文日文簡體中文
觀看分類:React 白話文運動其他系列

如果想要快速查找其他文章請點選目錄

成立 hogan.tech 的初衷是
希望每個正在這條路上探索的人,
都可以透過 Hogan.tech 嘗試進入程式領域。


前一篇則是介紹元件樹的狀態管理

  1. 狀態傳遞:由上而下
  2. 狀態傳遞:由下而上
  3. 狀態管理:Context

這一篇會繼續介紹useContext 的使用方法

  1. 加入Context
  2. 透過Context Consumer讀取資料
  3. 透過 useContext 讀取資料

加入Context

前一篇已經講解了使用 Context 來處理 React 狀態管理的好處,這邊直接上程式碼做範例

原先的App.js

import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import App from './components/App';

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

加上 Context 的App.js

import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import App from './components/App';
import { createContext } from 'react';


const colorData = [
    { id: "1", title: "red", color: "red", rating: 5 },
    { id: "2", title: "blue", color: "blue", rating: 2 },
    { id: "3", title: "green", color: "green", rating: 4 },
]


export const ColorContext = createContext();

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<ColorContext.Provider value={{colorData}} >
    <App />
</ColorContext.Provider>
);

這邊我們做了幾件事情,首先先將資料拉到對應的元件

接下來在根元件,宣告一個 ColorContext 指定為 createContext( ) 的物件

並且在 Element 中,新增 ColorContext.Provider 的標籤,並且資料為 colorData

這裡表示,在所有 App 元件以及子元件中,都會有 Context 狀態

這邊請注意 Context Provider 不一定要包裹在根元件,是可以包裹在局部元件的
且 Provider 也可以使用多個,不一定只能使用一個

接下來如果子元件需要使用 Context 中的狀態,可以透過 Context Consumer 來去存取狀態


透過Context Consumer讀取資料

上面已經在根元件加上了 Context 狀態,接下來就是在子元件做使用

先針對舊的檔案去做修改

原先的 ColorList.jsx

import React from 'react'
import Color from './Color'

export default function ColorList({ colors = [], onRemoveColor = f => f }) {
    if (!colors.length) return <div>No colors</div>;
    return (
        <div style={{ padding: 100 }}>
            {colors.map(color => <Color key={color.id} {...color} onRemove={onRemoveColor} />)}
        </div>
    )
}

加上 Context 的 ColorList.jsx

import React from 'react'
import { ColorContext } from '..';
import Color from './Color'


export default function ColorList() {
    return (
        <ColorContext.Consumer>
            {
                context => {
                    if (!context.colors.length) return <div>No colors</div>;
                    return (
                        <div style={{ padding: 100 }}>
                            {context.colors.map(color => <Color key={color.id} {...color} />)}
                        </div>
                    )
                }
            }
        </ColorContext.Consumer>
    )
}

這邊針對 ColorList 元件新增了 Context 的語法

首先先回傳一個 ColorContext.Consumer 標籤

接下來裡面的使用一個箭頭函式將原本的語法都包裹在裡面

只要使用 context 的關鍵字,就可以獲得對應的資料


透過 useContext 讀取資料

這邊我們使用 useContext 的寫法,應該可以發現簡潔許多

import React from 'react'
import { useContext } from 'react';
import { ColorContext } from '..';
import Color from './Color'


export default function ColorList() {
    const { colors } = useContext(ColorContext);
    if (!colors.length) return <div>No colors</div>;
    return (
        <div style={{ padding: 100 }}>
            {colors.map(color => <Color key={color.id} {...color} />)}
        </div>
    )
}

我們直接在需要使用該狀態的元件中

直接呼叫一個 useContext 並且把 Context 物件塞入,就可以直接做使用了

讀者可以比對一下兩個不同的寫法應該可以發現 useContext 的好處


結語

這邊講解了 useContext 的使用方法以及

如果使用 Context.Consumer 的話寫法又會是什麼

如果有任何建議與疑問也歡迎留言!

如果喜歡此系列文章,請不吝於按下喜歡及分享,讓更多人看到唷~


上一篇
React白話文運動17-React Hook-useContext 01
下一篇
React白話文運動19-React Hook-useMemo
系列文
React框架白話文運動30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言