第一式:单文件版
import React from 'react'
const ThemeContext = React.createContext('light')
function ThemeLink (props) {
return <ThemeContext.Consumer>
{ value => <p>link's theme is {value}</p> }
</ThemeContext.Consumer>
}
class ThemedButton extends React.Component {
render() {
const theme = this.context
return <div>
<p>button's theme is {theme}</p>
</div>
}
}
ThemedButton.contextType = ThemeContext
function Toolbar(props) {
return (
<div>
<ThemedButton />
<ThemeLink />
</div>
)
}
class App extends React.Component {
constructor(props) {
super(props)
this.state = {
theme: 'light'
}
}
render() {
return <ThemeContext.Provider value={this.state.theme}>
<Toolbar />
<hr/>
<button onClick={this.changeTheme}>change theme</button>
</ThemeContext.Provider>
}
changeTheme = () => {
this.setState({
theme: this.state.theme === 'light' ? 'dark' : 'light'
})
}
}
export default App
第二式:多文件版
index.js
import React from 'react'
import ThemedButton from './ThemedButton'
import ThemeLink from './ThemeLink'
import { ThemeContext } from './context-theme.js';
function Toolbar(props) {
return (
<div>
<ThemedButton />
<ThemeLink />
</div>
)
}
class App extends React.Component {
constructor(props) {
super(props)
this.state = {
theme: 'light'
}
}
render() {
return <ThemeContext.Provider value={this.state.theme}>
<Toolbar />
<hr/>
<button onClick={this.changeTheme}>change theme</button>
</ThemeContext.Provider>
}
changeTheme = () => {
this.setState({
theme: this.state.theme === 'light' ? 'dark' : 'light'
})
}
}
export default App
context-theme.js
import React from 'react'
export const ThemeContext = React.createContext('light')
ThemedButton.js
import React from 'react'
import { ThemeContext } from './context-theme.js';
class ThemedButton extends React.Component {
static contextType = ThemeContext
render() {
const theme = this.context
return <div>
<p>button's theme is {theme}</p>
</div>
}
}
export default ThemedButton
ThemeLink.js
import React from 'react'
import { ThemeContext } from './context-theme.js';
function ThemeLink (props) {
return <ThemeContext.Consumer>
{ value => <p>link's theme is {value}</p> }
</ThemeContext.Consumer>
}
export default ThemeLink
第三式:多文件版升级,第一步,封装context
index.js
import React from 'react'
import ThemedButton from './ThemedButton'
import ThemeLink from './ThemeLink'
import {
ThemeProvider,
ThemeConsumer,
} from './context-theme'
function Toolbar(props) {
return (
<div>
<ThemedButton />
<ThemeLink />
</div>
)
}
class App extends React.Component {
render() {
return (
<ThemeProvider>
<Toolbar />
<hr />
<ThemeConsumer>
{({ changeTheme }) => (
<button onClick={changeTheme}>change theme</button>
)}
</ThemeConsumer>
</ThemeProvider>
)
}
}
export default App
context-theme.js
import React from 'react'
export const ThemeContext = React.createContext({
theme: 'light',
changeTheme: () => { }
})
export class ThemeProvider extends React.Component {
changeTheme = () => {
this.setState({
theme: this.state.theme === 'light' ? 'dark' : 'light'
})
}
state = {
theme: 'light',
changeTheme: this.changeTheme
}
render() {
return (
<ThemeContext.Provider value={this.state}>
{this.props.children}
</ThemeContext.Provider>
)
}
}
export const ThemeConsumer = ThemeContext.Consumer
ThemedButton.js
import React from 'react'
import { ThemeContext } from './context-theme.js';
class ThemedButton extends React.Component {
static contextType = ThemeContext
render() {
const { theme } = this.context
return <div>
<p>button's theme is {theme}</p>
</div>
}
}
export default ThemedButton
ThemeLink.js
import React from 'react'
import { ThemeConsumer } from './context-theme.js';
function ThemeLink(props) {
return <ThemeConsumer>
{({ theme }) => <p>link's theme is {theme}</p>}
</ThemeConsumer>
}
export default ThemeLink
第三式:多文件版升级,第二步,采用hooks useContext优化函数式组件调用,用法比ThemeConsumer更简洁
index.js
import React, { useContext } from 'react'
import ThemedButton from './ThemedButton'
import ThemeLink from './ThemeLink'
import {
ThemeProvider,
ThemeContext,
} from './context-theme'
function Toolbar(props) {
return (
<div>
<ThemedButton />
<ThemeLink />
</div>
)
}
class App extends React.Component {
render() {
return (
<ThemeProvider>
<Toolbar />
<hr />
{/* <ThemeConsumer>
{({ changeTheme }) => (
<button onClick={changeTheme}>change theme</button>
)}
</ThemeConsumer> */}
<MidComponent />
</ThemeProvider>
)
}
}
function MidComponent() {
const { changeTheme } = useContext(ThemeContext)
return (
<div>
<button onClick={changeTheme}>change theme1</button>
</div>
)
}
export default App
context-theme.js
import React from 'react'
export const ThemeContext = React.createContext({
theme: 'light',
changeTheme: () => { }
})
export class ThemeProvider extends React.Component {
changeTheme = () => {
this.setState({
theme: this.state.theme === 'light' ? 'dark' : 'light'
})
}
state = {
theme: 'light',
changeTheme: this.changeTheme
}
render() {
return (
<ThemeContext.Provider value={this.state}>
{this.props.children}
</ThemeContext.Provider>
)
}
}
ThemedButton.js
import React from 'react'
import { ThemeContext } from './context-theme.js';
class ThemedButton extends React.Component {
static contextType = ThemeContext
render() {
const { theme } = this.context
return <div>
<p>button's theme is {theme}</p>
</div>
}
}
export default ThemedButton
ThemeLink.js
import React, { useContext } from 'react'
import { ThemeContext } from './context-theme.js';
function ThemeLink(props) {
const { theme } = useContext(ThemeContext)
return <p>link's theme is {theme}</p>
}
export default ThemeLink
第三式:多文件版升级,第三步,采用hooks useState优化context文件写法
index.js
import React, { useContext } from 'react'
import ThemedButton from './ThemedButton'
import ThemeLink from './ThemeLink'
import {
ThemeProvider,
ThemeContext,
} from './context-theme'
function Toolbar(props) {
return (
<div>
<ThemedButton />
<ThemeLink />
</div>
)
}
function App() {
return (
<ThemeProvider>
<Toolbar />
<hr />
<MidComponent />
</ThemeProvider>
)
}
function MidComponent() {
const { changeTheme } = useContext(ThemeContext)
return (
<div>
<button onClick={changeTheme}>change theme1</button>
</div>
)
}
export default App
context-theme.js
import React, { useState } from 'react'
export const ThemeContext = React.createContext({
theme: 'light',
changeTheme: () => { }
})
export const ThemeProvider = (props) => {
const [theme, setTheme] = useState('light')
const changeTheme = () => {
setTheme(theme === 'light' ? 'dark' : 'light')
}
return (
<ThemeContext.Provider value={{ theme, changeTheme }}>
{props.children}
</ThemeContext.Provider>
)
}
ThemedButton.js
import React from 'react'
import { ThemeContext } from './context-theme.js';
class ThemedButton extends React.Component {
static contextType = ThemeContext
render() {
const { theme } = this.context
return <div>
<p>button's theme is {theme}</p>
</div>
}
}
export default ThemedButton
ThemeLink.js
import React, { useContext } from 'react'
import { ThemeContext } from './context-theme.js';
function ThemeLink(props) {
const { theme } = useContext(ThemeContext)
return <p>link's theme is {theme}</p>
}
export default ThemeLink
参考博文