[Docs] Migrate with-context-api example to typescript (#40297)
## Documentation / Examples - [x] Make sure the linting passes by running `pnpm lint` - [x] The examples guidelines are followed from [our contributing doc](https://github.com/vercel/next.js/blob/canary/contributing.md#adding-examples)
This commit is contained in:
parent
fbf1c97eac
commit
16655c7924
7 changed files with 92 additions and 40 deletions
|
@ -1,31 +0,0 @@
|
|||
import { useReducer, useContext, createContext } from 'react'
|
||||
|
||||
const CounterStateContext = createContext()
|
||||
const CounterDispatchContext = 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(`Unknown 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)
|
57
examples/with-context-api/components/Counter.tsx
Normal file
57
examples/with-context-api/components/Counter.tsx
Normal file
|
@ -0,0 +1,57 @@
|
|||
import {
|
||||
useReducer,
|
||||
useContext,
|
||||
createContext,
|
||||
ReactNode,
|
||||
Dispatch,
|
||||
} from 'react'
|
||||
|
||||
type CounterState = number
|
||||
type CounterAction =
|
||||
| {
|
||||
type: 'INCREASE' | 'DECREASE'
|
||||
}
|
||||
| {
|
||||
type: 'INCREASE_BY'
|
||||
payload: number
|
||||
}
|
||||
|
||||
const CounterStateContext = createContext<CounterState>(0)
|
||||
const CounterDispatchContext = createContext<Dispatch<CounterAction>>(
|
||||
() => null
|
||||
)
|
||||
|
||||
const reducer = (state: CounterState, action: CounterAction) => {
|
||||
switch (action.type) {
|
||||
case 'INCREASE':
|
||||
return state + 1
|
||||
case 'DECREASE':
|
||||
return state - 1
|
||||
case 'INCREASE_BY':
|
||||
return state + action.payload
|
||||
default:
|
||||
throw new Error(`Unknown action: ${JSON.stringify(action)}`)
|
||||
}
|
||||
}
|
||||
|
||||
type CounterProviderProps = {
|
||||
children: ReactNode
|
||||
initialValue?: number
|
||||
}
|
||||
|
||||
export const CounterProvider = ({
|
||||
children,
|
||||
initialValue = 0,
|
||||
}: CounterProviderProps) => {
|
||||
const [state, dispatch] = useReducer(reducer, initialValue)
|
||||
return (
|
||||
<CounterDispatchContext.Provider value={dispatch}>
|
||||
<CounterStateContext.Provider value={state}>
|
||||
{children}
|
||||
</CounterStateContext.Provider>
|
||||
</CounterDispatchContext.Provider>
|
||||
)
|
||||
}
|
||||
|
||||
export const useCount = () => useContext(CounterStateContext)
|
||||
export const useDispatchCount = () => useContext(CounterDispatchContext)
|
|
@ -7,7 +7,12 @@
|
|||
},
|
||||
"dependencies": {
|
||||
"next": "latest",
|
||||
"react": "^17.0.2",
|
||||
"react-dom": "^17.0.2"
|
||||
"react": "^18.2.0",
|
||||
"react-dom": "^18.2.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "18.7.15",
|
||||
"@types/react": "16.9.17",
|
||||
"typescript": "4.8.2"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,11 +1,10 @@
|
|||
import type { AppProps } from 'next/app'
|
||||
import { CounterProvider } from '../components/Counter'
|
||||
|
||||
function MyApp({ Component, pageProps }) {
|
||||
export default function MyApp({ Component, pageProps }: AppProps) {
|
||||
return (
|
||||
<CounterProvider>
|
||||
<Component {...pageProps} />
|
||||
</CounterProvider>
|
||||
)
|
||||
}
|
||||
|
||||
export default MyApp
|
|
@ -1,3 +1,4 @@
|
|||
import type { MouseEvent } from 'react'
|
||||
import Link from 'next/link'
|
||||
import { useCount, useDispatchCount } from '../components/Counter'
|
||||
|
||||
|
@ -5,11 +6,11 @@ const AboutPage = () => {
|
|||
const count = useCount()
|
||||
const dispatch = useDispatchCount()
|
||||
|
||||
const handleIncrease = (event) =>
|
||||
const handleIncrease = (event: MouseEvent<HTMLButtonElement>) =>
|
||||
dispatch({
|
||||
type: 'INCREASE',
|
||||
})
|
||||
const handleIncrease15 = (event) =>
|
||||
const handleIncrease15 = (event: MouseEvent<HTMLButtonElement>) =>
|
||||
dispatch({
|
||||
type: 'INCREASE_BY',
|
||||
payload: 15,
|
|
@ -1,3 +1,4 @@
|
|||
import type { MouseEvent } from 'react'
|
||||
import Link from 'next/link'
|
||||
import { useCount, useDispatchCount } from '../components/Counter'
|
||||
|
||||
|
@ -5,11 +6,11 @@ const IndexPage = () => {
|
|||
const count = useCount()
|
||||
const dispatch = useDispatchCount()
|
||||
|
||||
const handleIncrease = (event) =>
|
||||
const handleIncrease = (event: MouseEvent<HTMLButtonElement>) =>
|
||||
dispatch({
|
||||
type: 'INCREASE',
|
||||
})
|
||||
const handleDecrease = (event) =>
|
||||
const handleDecrease = (event: MouseEvent<HTMLButtonElement>) =>
|
||||
dispatch({
|
||||
type: 'DECREASE',
|
||||
})
|
20
examples/with-context-api/tsconfig.json
Normal file
20
examples/with-context-api/tsconfig.json
Normal file
|
@ -0,0 +1,20 @@
|
|||
{
|
||||
"compilerOptions": {
|
||||
"target": "es5",
|
||||
"lib": ["dom", "dom.iterable", "esnext"],
|
||||
"allowJs": true,
|
||||
"skipLibCheck": true,
|
||||
"strict": true,
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"noEmit": true,
|
||||
"incremental": true,
|
||||
"esModuleInterop": true,
|
||||
"moduleResolution": "node",
|
||||
"module": "esnext",
|
||||
"resolveJsonModule": true,
|
||||
"isolatedModules": true,
|
||||
"jsx": "preserve"
|
||||
},
|
||||
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"],
|
||||
"exclude": ["node_modules"]
|
||||
}
|
Loading…
Reference in a new issue