提交 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. ...@@ -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. 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' import App from 'next/app'
/* First we import our provider */ import { CounterProvider } from '../components/Counter'
import CounterProvider from '../components/CounterProvider'
class MyApp extends App { class MyApp extends App {
render () { render () {
const { Component, pageProps } = this.props const { Component, pageProps } = this.props
return ( return (
/* Then we wrap our components with the provider */
<CounterProvider> <CounterProvider>
<Component {...pageProps} /> <Component {...pageProps} />
</CounterProvider> </CounterProvider>
......
import React, { Component } from 'react' import React from 'react'
/* First we import the consumer */
import { CounterConsumer } from '../components/CounterProvider'
import Link from 'next/link' import Link from 'next/link'
import { useCount, useDispatchCount } from '../components/Counter'
export default class about extends Component { const AboutPage = () => {
render () { const count = useCount()
return ( const dispatch = useDispatchCount()
/* Then we use our context through render props */
<CounterConsumer> const handleIncrease = event =>
{({ count, increase, increaseBy }) => ( dispatch({
<div> type: 'INCREASE'
<h1>ABOUT</h1> })
<p>Counter: {count}</p> const handleIncrease15 = event =>
<button onClick={increase}>Increase</button> dispatch({
<button type: 'INCREASE_BY',
onClick={() => { payload: 15
increaseBy(15) })
}}
> return (
Increase By 15 <>
</button> <h1>ABOUT</h1>
<p> <p>Counter: {count}</p>
<Link href='/'> <button onClick={handleIncrease}>Increase</button>
<a>Home</a> <button onClick={handleIncrease15}>Increase By 15</button>
</Link> <p>
</p> <Link href='/'>
</div> <a>Home</a>
)} </Link>
</CounterConsumer> </p>
) </>
} )
} }
export default AboutPage
import React, { Component } from 'react' import React from 'react'
import Link from 'next/link' import Link from 'next/link'
/* First we import the consumer */ import { useCount, useDispatchCount } from '../components/Counter'
import { CounterConsumer } from '../components/CounterProvider'
export default class index extends Component { const IndexPage = () => {
render () { const count = useCount()
return ( const dispatch = useDispatchCount()
/* Then we use our context through render props */
<CounterConsumer> const handleIncrease = event =>
{({ count, increase, decrease }) => ( dispatch({
<div> type: 'INCREASE'
<h1>HOME</h1> })
<p>Counter: {count}</p> const handleDecrease = event =>
<button onClick={increase}>Increase</button> dispatch({
<button onClick={decrease}>Decrease</button> type: 'DECREASE'
<p> })
<Link href='/about'>
<a>About</a> return (
</Link> <>
</p> <h1>HOME</h1>
</div> <p>Counter: {count}</p>
)} <button onClick={handleIncrease}>Increase</button>
</CounterConsumer> <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.
先完成此消息的编辑!
想要评论请 注册