[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:
Henrik Wenz 2022-09-07 11:14:54 +02:00 committed by GitHub
parent fbf1c97eac
commit 16655c7924
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 92 additions and 40 deletions

View file

@ -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)

View 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)

View file

@ -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"
}
}

View file

@ -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

View file

@ -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,

View file

@ -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',
})

View 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"]
}