上下文 API 是一種很好的方法,讓我們在應用程式中傳遞狀態,而不需要使用 props。
上下文 API 的引入可以讓我們在應用程式中傳遞狀態 (並且允許該狀態在多個組件之間更新),而不需要使用 props。
React 團隊建議,在只有幾個層級的子組件需要傳遞狀態的情況下,仍然使用 props,因為相比於上下文 API,props 是更簡單的 API。
在許多情況下,使用上下文 API 可以避免使用 Redux,大大簡化我們的應用程式,同時學習如何使用 React。
它是如何運作的呢?
你可以使用 React.createContext()
創建一個上下文 (Context):
const { Provider, Consumer } = React.createContext()
然後,你可以創建一個包裹組件 (wrapper component),並返回一個 Provider 組件,在其中加入所有你希望訪問上下文的組件:
class Container extends React.Component {
constructor(props) {
super(props)
this.state = {
something: 'hey'
}
}
render() {
return (
<Provider value={{ state: this.state }}>{this.props.children}</Provider>
)
}
}
class HelloWorld extends React.Component {
render() {
return (
<Container>
<Button />
</Container>
)
}
}
我將這個組件命名為 Container,因為它將是一個全局的提供者 (Provider)。你也可以創建更小的上下文 (Context)。
在被 Provider 包裹的組件中,你可以使用 Consumer 組件來使用該上下文:
class Button extends React.Component {
render() {
return (
<Consumer>
{context => <button>{context.state.something}</button>}
</Consumer>
)
}
}
你還可以將函數傳遞給 Provider 的 value,並且這些函數將被 Consumer 使用以更新上下文的狀態:
<Provider value={{
state: this.state,
updateSomething: () => this.setState({something: 'ho!'})}}>
{this.props.children}
</Provider>
/* ... */
<Consumer>
{(context) => (
<button onClick={context.updateSomething}>{context.state.something}</button>
)}
</Consumer>
你可以在 這個 Glitch 中看到這個示例。
你可以創建多個上下文,將狀態分佈在多個組件中,同時使它可以被任何你想要的組件訪問。
當在多個文件中使用時,你可以在一個文件中創建上下文,然後在所有使用它的地方導入:
//context.js
import React from 'react'
export default React.createContext()
//component1.js
import Context from './context'
//... 使用 Context.Provider
//component2.js
import Context from './context'
//... 使用 Context.Consumer