一連好幾天都在講 useState 和 useEffect,讓我們來換換口味,講講什麼是 useContext
之前我們在用props 傳遞我們要的值時,我們都要一層一層的傳遞 props
也因為每一次都要這樣從父層將傳資料一層一層的傳下來到達我們要的子層,但是我們卻不知道到底哪一層真的使用到了,那我可有其他的方式嗎?那就必須提到我們今天的主題 useContext 了
Context Object 是被 createContext()
這個 API 所建立,裡面有兩個子元件
import { createContext } from "react";
const TextContext = createContext(context);
const { Provider, Consumer } = TextContext;
那我們要怎麼樣用 Provider, Consumer 傳遞接收我們要的值
首先我做了這個例子
import { createContext } from "react";
import { Parent } from "./Parent";
import "./index.css"
const context = "我是 useContext"
export const TextContext = createContext(context);
function App() {
return (
<TextContext.Provider value={context}>
<div className="border">
<Parent />
</div>
</TextContext.Provider>
);
}
export default App;
注意!!!!!
Context 目前的值是取決於由上層 component 距離最近的<MyContext.Provider>
的value
prop。
以我們的例子來說現在的值就是context = "我是 useContext"
沒錯,在上面也有提到 Provider: 傳遞 value 這個值
那接下來就是我們要如何接球了 那就是用 Consumer: 接收 value 這個值
讓我們看看是怎麼實踐的
// Child.js
import "./index.css"
import { TextContext } from "./App"
import { useContext } from "react";
const Child = () => {
return (
<TextContext.Consumer>
{ text =>
<div className="child" >
child
{text}
</div>
}
</TextContext.Consumer>
)
}
export { Child }
結果會是這樣的,我們可以直接從第一層傳遞給最底下的子層
這樣寫感覺還是有點小複雜,讓我們換成 useContext 來做吧,我們可以在
TextContext.Consumer 接收 value 的地方換成 useContext
// Child.js
import "./index.css"
import { TextContext } from "./App"
import { useContext } from "react";
const Child = () => {
const text = useContext(TextContext);
return (
<div className="child" >
child 第三層
{text}
</div>
)
}
export { Child }
不要忘記 useContext
的參數必需為 context object 自己:
useContext(MyContext)
useContext(MyContext.Consumer)
useContext(MyContext.Provider)
所以我們在 App.js
,做出了 TextContext
這個 context 物件
const TextContext = createContext(context);
所以我們才會寫出這行
const text = useContext(TextContext);
我認為 useContext
並不能取代原本 props 的方法,因為 context 傳遞的 value 改變時底下所有子元件都會 re-render,
在 React 中我們常常會去改變我們變數的值,像是前幾天介紹的 useState、useEffect,
所以會造成其他沒有沒有用到 useContext
元件的重複渲染
所以還是要依照使用情境的不同去做選擇
今天介紹了 useContext 這個 Hook ,有他的方便之處,也有必須考慮的使用情境,明天將會持續下去,一起繼續探索 React 的世界