楔子
useContext 是 hook 系列很常使用的東西,通常就在「跨」 components 之間使用,有時加減也好用也有點濫用,說說比較常使用的情境吧..
例如像 Global Theme 在所有的 component 都包上一層,像 Material UI 就採用這種模式..
那像假設 firebase Oauth 的情況時,要用嗎?還是可以用 custom hook?其實這二種方式都有人用,看自已的習慣而以..
一般式
這是比較正常的方式,最外層包一個 Provider 再利用 render prop 來操作
import React from 'react';
export const UserContext = React.createContext();
export default function App() {
return (
<UserContext.Provider value="user">
<User />
</UserContext.Provider>
)
}
function User() {
return (
<UserContext.Consumer>
{value => <h1>{value}</h1>}
</UserContext.Consumer>
)
}
Kent c dodds
但其實如果使用 Kent 的起手式,其實蠻優美的.. Kent useContext code
用一個 component 當 Provider 同時也可以在那個 Provider 內使用 useEffect 之類的功用..
import * as React from 'react'
const CountContext = React.createContext()
function CountProvider(props) {
// 在這可以塞更多 hook 的變數或 function
const [count, setCount] = React.useState(0)
const value = [count, setCount]
return <CountContext.Provider value={value} {...props} />
}
function useCount() {
const context = React.useContext(CountContext)
if (!context) {
throw new Error('useCount must be used within a CountProvider')
}
return context
}
function CountDisplay() {
const [count] = useCount()
return <div>The current count is {count}</div>
}
function Counter() {
const [, setCount] = useCount()
const increment = () => setCount(c => c + 1)
return <button onClick={increment}>Increment count</button>
}
function App() {
return (
<div>
<CountProvider>
<CountDisplay />
<Counter />
</CountProvider>
</div>
)
}
export default App