[英]Dispatch in useContext not working on handleClick
I am trying to do a simple dispatch to the reducer, however I am not sure on why it's not updating or triggering changes to the context state.我正在尝试对减速器进行简单的调度,但是我不确定它为什么不更新或触发对上下文 state 的更改。
Below is my Provider code along with it's custom hook.下面是我的 Provider 代码及其自定义钩子。
import React, { FC, Dispatch, createContext, useReducer, useContext, ReactNode } from 'react';
export const SET_SHOW = "SET_SHOW";
interface SetShow {
type: typeof SET_SHOW;
show: boolean;
}
type AppActionTypes = SetShow;
interface AppState {
show: boolean;
}
interface ContextType {
state: AppState;
dispatch: Dispatch<AppActionTypes>;
}
const INITIAL_STATE = {
show: false
}
const AppContext = createContext<ContextType>(
{
state: INITIAL_STATE,
dispatch: () => null
}
);
const AppReducer = (state: AppState, action: AppActionTypes) => {
switch(action.type){
case SET_SHOW: {
return {
show: action.show
}
}
default:
throw new Error("Action is invalid");
}
};
export const AppProvider: FC = (props: ReactNode) => {
const initialState = INITIAL_STATE;
const [ state, dispatch ] = useReducer(AppReducer, initialState);
return <AppContext.Provider value={{state, dispatch }} {...props} />;
};
export const useProvider = (): ContextType => {
const context = useContext(AppContext);
if(!context){
throw new Error("useProvider must be used within AppContext");
}
const {state, dispatch} = context;
return {
state, dispatch
};
};
And below is my app component下面是我的应用程序组件
import React, { FC } from 'react';
import './App.css';
import { AppProvider, useProvider, SET_SHOW } from './hooks/useProvider';
const App: FC = (): JSX.Element => {
const { state, dispatch } = useProvider();
const handleClick = () =>{
dispatch({
type: SET_SHOW,
show: !state.show
});
console.log(state.show);
};
return (
<AppProvider>
<div className="App">
{ state.show && "Hello World!" }
<button onClick={handleClick}>
Show message!
</button>
</div>
</AppProvider>
);
};
export default App;
I already tried putting an breakpoints on the reducer but somehow it still doesn't trigger the dispatch call.我已经尝试在减速器上放置一个断点,但不知何故它仍然没有触发调度调用。
There are 2 problems here.这里有2个问题。
AppProvider
should be a parent of App
. AppProvider
应该是App
的父级。 This way it can fully access the context.const rootElement = document.getElementById("root");
render(
<AppProvider>
<App />
</AppProvider>,
rootElement
);
dispatch
is changing the state async so console.log
just after dispatch
logs the old value. dispatch
正在更改 state 异步,因此dispatch
后的console.log
记录旧值。 You should "watch" the change using useEffect
.useEffect
“观察”变化。React.useEffect(() => {
console.log("effect", state.show);
}, [state.show]);
A working demo: https://codesandbox.io/s/peaceful-blackwell-ohd0y?file=/src/index.tsx工作演示: https://codesandbox.io/s/peaceful-blackwell-ohd0y?file=/src/index.tsx
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.