const { count, setCount } = useCountState();
如同 Recoil 當中的 atom,或是可以參考更早之前介紹的文章 「 實現跨元件資料共享, useContext 」,我們需要的值有:
export const CountContext = createContext({
count: 0,
setCount: null
});
實際做出 count 這個 global state 跟 他的 setter function ,並提供給 Context Provider
export const CountProvider = ({ children }) => {
const [count, setCount] = useState(0);
const defaultValue = {
count,
setCount
};
return (
<CountContext.Provider value={defaultValue}>
{children}
</CountContext.Provider>
);
};
export default function App() {
return (
<div className="App">
<CountProvider>
<h1>Hello CodeSandbox</h1>
<Comp1 />
<Comp2 />
</CountProvider>
</div>
);
}
還記得在 「 實現跨元件資料共享, useContext 」 介紹時,我們認識了 useContext
這個 API ,
我們會在需要使用共享變數的地方,呼叫這個 hook , 並且明確帶入我們想要獲得的狀態 像是 const { theme } = useContext(ThemeContext)
或 const { count, setCount } = useContext(CountContext)
。 此時在需要使用到這份 state 的檔案當中,就必須要明確引入 CountContext 、 ThemeContext 。
import React, { useContext } from "react";
import { CountContext } from "../somewhere/"
import { ThemeContext } from "./ThemeProvider";
const Comp1 = () =>{
const { theme } = useContext(ThemeContext);
const { count, setCount } = useContext(CountContext);
return (
<div style={{ backgroundColor: theme.background }}>
<h2>count in Comp1 :{count} </h2>
<button onClick={() => setCount(count + 1)}>increment</button>
</div>
}
但有了 Custom hook 之後...,我們就可以如此縮寫。
export const useCountState = () => useContext(CountContext);
使我們可以把這個 context 封裝起來,不需要在其他元件內不斷 import 入,許多 context 如: CountContext 、 ThemeContext 。
import React from "react";
import { useCountState } from "./CountProvider";
const Comp1 = () => {
const { count, setCount } = useCountState();
return (
<div>
<h2>count in Comp1 :{count} </h2>
<button onClick={() => setCount(count + 1)}>increment</button>
</div>
);
};