提交 fd0ba93f 编写于 作者: H Henrik Wenz 提交者: Joe Haddad

Refactor with-context-api example to use functional components (#9092)

上级 2874a3e0
......@@ -43,8 +43,8 @@ This example shows how to use react context api in our app.
It provides an example of using `pages/_app.js` to include the context api provider and then shows how both the `pages/index.js` and `pages/about.js` can both share the same data using the context api consumer.
The `pages/index.js` shows how to, from the home page, increment and decrement the context data by 1 (a hard code value in the context provider itself).
We start of by creating two contexts. One that actually never changes (`CounterDispatchContext`) and one that changes more often (`CounterStateContext`).
The `pages/about.js` shows how to, from the about page, how to pass an increment value from the about page into the context provider itself.
The `pages/index.js` shows how to, from the home page, increment and decrement the context data by 1 (a hard code value in the context provider itself).
\*_Based on WesBos example_.
The `pages/about.js` shows how to pass an increment value from the about page into the context provider itself.
import React, { useReducer, useContext } from 'react'
const CounterStateContext = React.createContext()
const CounterDispatchContext = React.createContext()
const reducer = (state, action) => {
switch (action.type) {
case 'INCREASE':
return state + 1
case 'DECREASE':
return state - 1
case 'INCREASE_BY':
return state + action.payload
default:
throw new Error(`Unkown action: ${action.type}`)
}
}
export const CounterProvider = ({ children }) => {
const [state, dispatch] = useReducer(reducer, 0)
return (
<CounterDispatchContext.Provider value={dispatch}>
<CounterStateContext.Provider value={state}>
{children}
</CounterStateContext.Provider>
</CounterDispatchContext.Provider>
)
}
export const useCount = () => useContext(CounterStateContext)
export const useDispatchCount = () => useContext(CounterDispatchContext)
import React, { Component } from 'react'
/* First we will make a new context */
const CounterContext = React.createContext()
/* Then create a provider Component */
class CounterProvider extends Component {
state = {
count: 0,
increase: () => {
this.setState((state, props) => ({
count: state.count + 1
}))
},
increaseBy: val => {
this.setState((state, props) => ({
count: state.count + val
}))
},
decrease: () => {
this.setState((state, props) => ({
count: state.count - 1
}))
}
}
render () {
return (
<CounterContext.Provider value={this.state}>
{this.props.children}
</CounterContext.Provider>
)
}
}
/* then make a consumer which will surface it */
const CounterConsumer = CounterContext.Consumer
export default CounterProvider
export { CounterConsumer }
import App from 'next/app'
/* First we import our provider */
import CounterProvider from '../components/CounterProvider'
import { CounterProvider } from '../components/Counter'
class MyApp extends App {
render () {
const { Component, pageProps } = this.props
return (
/* Then we wrap our components with the provider */
<CounterProvider>
<Component {...pageProps} />
</CounterProvider>
......
import React, { Component } from 'react'
/* First we import the consumer */
import { CounterConsumer } from '../components/CounterProvider'
import React from 'react'
import Link from 'next/link'
import { useCount, useDispatchCount } from '../components/Counter'
export default class about extends Component {
render () {
return (
/* Then we use our context through render props */
<CounterConsumer>
{({ count, increase, increaseBy }) => (
<div>
<h1>ABOUT</h1>
<p>Counter: {count}</p>
<button onClick={increase}>Increase</button>
<button
onClick={() => {
increaseBy(15)
}}
>
Increase By 15
</button>
<p>
<Link href='/'>
<a>Home</a>
</Link>
</p>
</div>
)}
</CounterConsumer>
)
}
const AboutPage = () => {
const count = useCount()
const dispatch = useDispatchCount()
const handleIncrease = event =>
dispatch({
type: 'INCREASE'
})
const handleIncrease15 = event =>
dispatch({
type: 'INCREASE_BY',
payload: 15
})
return (
<>
<h1>ABOUT</h1>
<p>Counter: {count}</p>
<button onClick={handleIncrease}>Increase</button>
<button onClick={handleIncrease15}>Increase By 15</button>
<p>
<Link href='/'>
<a>Home</a>
</Link>
</p>
</>
)
}
export default AboutPage
import React, { Component } from 'react'
import React from 'react'
import Link from 'next/link'
/* First we import the consumer */
import { CounterConsumer } from '../components/CounterProvider'
import { useCount, useDispatchCount } from '../components/Counter'
export default class index extends Component {
render () {
return (
/* Then we use our context through render props */
<CounterConsumer>
{({ count, increase, decrease }) => (
<div>
<h1>HOME</h1>
<p>Counter: {count}</p>
<button onClick={increase}>Increase</button>
<button onClick={decrease}>Decrease</button>
<p>
<Link href='/about'>
<a>About</a>
</Link>
</p>
</div>
)}
</CounterConsumer>
)
}
const IndexPage = () => {
const count = useCount()
const dispatch = useDispatchCount()
const handleIncrease = event =>
dispatch({
type: 'INCREASE'
})
const handleDecrease = event =>
dispatch({
type: 'DECREASE'
})
return (
<>
<h1>HOME</h1>
<p>Counter: {count}</p>
<button onClick={handleIncrease}>Increase</button>
<button onClick={handleDecrease}>Decrease</button>
<p>
<Link href='/about'>
<a>About</a>
</Link>
</p>
</>
)
}
export default IndexPage
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册