useReducer + useContext + createContext
Posted 落霞与孤鹜齐飞
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了useReducer + useContext + createContext相关的知识,希望对你有一定的参考价值。
正常的 Increment 和 Decrement改变 Display 的 count
import React, { useState } from \'react\'
function Display(props) {
return <h1>Counter value : {props.counter}</h1>
}
function Increment(props) {
return <button onClick={() => props.addToCounter(1)}>Increment</button>
}
function Decrement(props) {
return <button onClick={() => props.addToCounter(-1)}>Decrement</button>
}
function Index() {
const [counter, setCounter] = useState(0);
const addToCounter = value => setCounter(counter + value);
return (
<div>
<h1>Teste</h1>
<Display counter={counter} />
<Increment addToCounter={addToCounter} />
<Decrement addToCounter={addToCounter} />
</div>
)
}
export default Index
一步一步来改装
使用useContext来替换Display组件中的props
import React, { useState, useContext, createContext } from \'react\' const CounterContext = createContext({ counter: 0 }) function Display(props) { const context = useContext(CounterContext) return <h1>Counter value : {context.counter}</h1> }
编写reducer去代替组件中的addToCounter方法
import React, { useState, useContext, createContext, useReducer } from \'react\' const CounterContext = createContext({ counter: 0 }) function Display(props) { const context = useContext(CounterContext) return <h1>Counter value : {context.state.counter}</h1> } function Increment(props) { const context = useContext(CounterContext) return <button onClick={() => context.dispatch({ type: \'ADD_TO_COUNTER\', value: 1 })}>Increment</button> } function Decrement(props) { const context = useContext(CounterContext) return <button onClick={() => context.dispatch({ type: \'ADD_TO_COUNTER\', value: -1 })}>Decrement</button> } function Index() { const [state, dispatch] = useReducer((state, action) => { switch (action.type) { case \'ADD_TO_COUNTER\': return { ...state, counter: state.counter + action.value } default: return state } }, { counter: 0 }) return ( <CounterContext.Provider value={{state, dispatch}}> <h1>Teste</h1> <Display /> <Increment /> <Decrement /> </CounterContext.Provider> ) } export default Index
把CounterContext.Provider抽成组件拿出来
function CounterContextProvider(props) { const [state, dispatch] = useReducer((state, action) => { switch (action.type) { case \'ADD_TO_COUNTER\': return { ...state, counter: state.counter + action.value } default: return state } }, { counter: 0 }) return ( <CounterContext.Provider value={{ state, dispatch }}> {props.children} </CounterContext.Provider> ) } function Index() { return ( <CounterContextProvider> <h1>Teste</h1> <Display /> <Increment /> <Decrement /> </CounterContextProvider> ) }
把组件分一下文件就是
index.jsx
import React, { useState, useContext, createContext, useReducer } from \'react\' import Display from \'../components/ComB\' import {Increment, Decrement} from \'../components/ComA\' export const CounterContext = createContext({ counter: 0 }) function CounterContextProvider(props) { const [state, dispatch] = useReducer((state, action) => { switch (action.type) { case \'ADD_TO_COUNTER\': return { ...state, counter: state.counter + action.value } default: return state } }, { counter: 0 }) return ( <CounterContext.Provider value={{ state, dispatch }}> {props.children} </CounterContext.Provider> ) } function Index(props) { return ( <CounterContextProvider> <h1>Teste</h1> <Display /> <Increment /> <Decrement /> </CounterContextProvider> ) } export default Index
comA.jsx
import React, { useContext } from "react" import { CounterContext } from \'../pages/index.tsx\' export function Increment(props) { const context = useContext(CounterContext) return <button onClick={() => context.dispatch({ type: \'ADD_TO_COUNTER\', value: 1 })}>Increment</button> } export function Decrement(props) { const context = useContext(CounterContext) return <button onClick={() => context.dispatch({ type: \'ADD_TO_COUNTER\', value: -1 })}>Decrement</button> }
comB.jsx
import React, {useContext} from \'react\' import {CounterContext} from \'../pages/index\' function ComB() { const context = useContext(CounterContext) return <h1>Counter value : {context.state.counter}</h1> } export default ComB
以上是关于useReducer + useContext + createContext的主要内容,如果未能解决你的问题,请参考以下文章
使用 React useContext 和 useReducer 时出现打字稿错误
如何测试组件中的react useContext useReducer调度
useContext 和 useReducer Hooks 不起作用。错误:无法读取未定义的属性“状态”
React TS useContext useReducer 钩子