在 React 中,useContext()
是一個 Hook,用來讓你在函式元件中輕鬆地存取 context 資料,避免繁瑣的 props
傳遞。以下是一步步的教學與示例程式碼:
import React, {createContext} from 'react';
// 建立一個 Context,預設值可以是任何你想要的資料或空值
const MyContext = createContext({ user: null });
export default MyContext;
使用 Context Provider 將資料傳遞到元件樹中。所有被 Provider
包裹的子元件,都可以透過這個 Context
存取資料:
import React, { useState } from 'react';
import MyContext from './MyContext';
import Header from './Header';
function TestComponent() {
const [user, setUser] = useState({ name: 'Alice' });
return (
<MyContext.Provider value={{ user, setUser }}>
<Header />
</MyContext.Provider>
);
}
export default TestComponent;
在子元件中,你可以使用 useContext()
來存取剛剛提供的 Context
資料,無需透過 props
傳遞:
import React, { useContext } from 'react';
import MyContext from './MyContext';
function Header() {
// 直接存取 context 中的資料
const { user } = useContext(MyContext);
return (
<header>
<h1>歡迎, {user.name}!</h1>
</header>
);
}
export default Header;
效果:
下面提供兩個完整的範例,一個是使用 props 傳遞兩層(父元件 → 子元件 → 孫元件),另一個則是使用 useContext
來改寫,省去中間層級的 props
傳遞。
在這個範例中,父元件中定義了 user 狀態,並透過 props 傳遞到子元件,再由子元件傳給孫元件,孫元件可以讀取與更新 user 狀態。
Parent.js
import React, { useState } from 'react';
import Child from './Child';
function Parent() {
const [user, setUser] = useState({ name: 'Alice' });
return (
<div>
<h1>父元件</h1>
{/* 將 user 與 setUser 透過 props 傳給 Child */}
<Child user={user} setUser={setUser} />
</div>
);
}
export default Parent;
Child.js
import React from 'react';
import GrandChild from './GrandChild';
function Child(Props) {
return (
<div>
<h2>子元件</h2>
{/* 再將資料繼續傳給 GrandChild */}
<GrandChild user={Props.user} setUser={Props.setUser} />
</div>
);
}
export default Child;
GrandChild.js
import React from 'react';
function GrandChild(Props) {
const changeUser = () => {
Props.setUser({ name: 'Bob' });
};
return (
<div>
<h3>孫元件</h3>
<p>使用者名稱:{Props.user.name}</p>
<button onClick={changeUser}>更改使用者</button>
</div>
);
}
export default GrandChild;
props
傳遞會變得繁瑣。在父元件中我們會建立並 export 一個 Context
(這裡命名為 MyContext
),其他元件則直接引入使用,不再需要 props
傳遞。
Parent.js
import React, { useState, createContext } from 'react';
import Child from './Child';
// 在父元件中建立並 export Context
export const MyContext = createContext();
function Parent() {
const [user, setUser] = useState({ name: 'Alice' });
return (
<MyContext.Provider value={{ user, setUser }}>
<div>
<h1>父元件</h1>
<Child />
</div>
</MyContext.Provider>
);
}
export default Parent;
Child.js
import React from 'react';
import GrandChild from './GrandChild';
function Child() {
return (
<div>
<h2>子元件</h2>
{/* 直接呼叫 GrandChild,不需要傳遞 props */}
<GrandChild />
</div>
);
}
export default Child;
GrandChild.js
import React, { useContext } from 'react';
import { MyContext } from './Parent';
function GrandChild() {
// 直接使用 useContext 取得資料
const { user, setUser } = useContext(MyContext);
const changeUser = () => {
setUser({ name: 'Bob' });
};
return (
<div>
<h3>孫元件</h3>
<p>使用者名稱:{user.name}</p>
<button onClick={changeUser}>更改使用者</button>
</div>
);
}
export default GrandChild;