寫了這麼久 React,發現我的筆記都沒整理過,趁最近比較不忙來清理一下筆記 XD
這次要分享的是跨元件處理狀態的 hook – useContext。

使用情境

一般寫 React 時,如果需要將元件的狀態傳遞的話,如果是簡單的父子元件傳遞,可以用 props 來傳。但如果是很多層的情況,或是同層的子組件要互傳狀態的話,可能用 props 就不是這麼適合。當然也可以使用一些狀態管理的套件,例如:Redux(之後會找時間分享)。不過,其實 React 內建就有 useContext 這個 hook,這邊就來示範一下作法:

使用的情境是分別有兩個元件,有一個輸入框 - A,跟一個顯示輸入的文字 - B,如果 A 改變輸入的文字,那麼 B 就會即時顯示該文字。

初始設置

以下是原始的程式碼,可以看到分別有 InputText.js 跟 ShowText.js 兩個元件放在 App.js 中

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
// App.js
import InputText from './InputText'
import ShowText from './ShowText'

export default function App() {

return (
<div className='App'>
<InputText />
<ShowText />
</div>
)
}

// InputText
const InputText = () => {

return (
<div>
<input type="text" />
</div>
);
};

export default InputText;

// ShowText
const ShowText = () => {

return (
<div>
<p>Hello World</p>
</div>
);
};

export default ShowText;

使用 createContext 建立共用狀態

首先 import createContext,並且設一個變數,然後 export 該變數,例如: AppContext,等等會給其他元件使用。

1
2
3
import { createContext } from 'react'

export const AppContext = createContext()

接著在要傳遞狀態的父元件,在這個範例也就是 App.js 中,在最外層用 AppContext 將所有子元件包起來,並且設置 value。

1
2
3
4
5
6
<AppContext.Provider value={{}}>
<div>
<InputText />
<ShowText />
</div>
</AppContext.Provider>

可以發現 value 是一個物件,裡面可以放入任何狀態,等等就可以讓其他元件使用,這邊用一個 useState 來處理狀態。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
import { createContext, useState } from 'react'

export default function App() {
const [text, setText] = useState('Hello World')

return (
<AppContext.Provider value={{ text, setText }}>
<div className='App'>
<InputText />
<ShowText />
</div>
</AppContext.Provider>
)
}

利用 useContext 讓其他元件處理狀態

InputText

首先 import useContext,並且參數帶入一開始建立的 AppContext,然後從裡面取出 setText 來變更狀態。

1
2
3
4
5
6
7
8
9
10
11
12
import { useContext } from 'react'
import { AppContext } from './App'

const InputText = () => {
const { text, setText } = useContext(AppContext)

return (
<div>
<input type='text' value={text} onChange={(e) => setText(e.target.value)} />
</div>
)
}

ShowText

一樣 import useContext,並且參數帶入一開始建立的 AppContext,然後從裡面取出 text 來顯示狀態。

1
2
3
4
5
6
7
8
9
10
11
12
import { useContext } from 'react'
import { AppContext } from './App'

const ShowText = () => {
const { text } = useContext(AppContext)

return (
<div>
<p>{text}</p>
</div>
)
}

這樣本次範例就完成了,下面有 Demo 可以試玩看看 ⬇️