- States
States
代码语言:javascript复制Prepare Initial States State Type
export const initialState = {
attributeA: {
propertyA1: ``,
},
attributeB: {
propertyB1: 0,
},
num: 0,
};
export type StateType = {
attributeA: {
propertyA1: string;
};
attributeB: {
propertyB1: number;
};
num: number;
};
Action
代码语言:javascript复制Prepare actions
type ActionMap<M extends { [index: string]: any }> = {
[Key in keyof M]: M[Key] extends undefined
? {
type: Key;
}
: {
type: Key;
payload: M[Key];
};
};
// eslint-disable-next-line no-shadow
export enum ActionType {
setAttrA = `SET_ATTR_A`,
setAttrB = `SET_ATTR_B`,
add = `ADD`,
reduce = `REDUCE`,
}
/**
* @name ActionPayload
* @description Type def for action payloads,
*/
type ActionPayload = {
[ActionType.setAttrA]: {
propertyA1: string;
};
[ActionType.setAttrB]: {
propertyB1: number;
};
/* Not payloads required for below 2 actions */
[ActionType.add]: undefined;
[ActionType.reduce]: undefined;
};
/**
* @name ActionPayloadDataType
* @description The type def of the Action Payload Data
*/
export type ActionPayloadDataType = ActionMap<ActionPayload>[keyof ActionMap<ActionPayload>];
Reducer
代码语言:javascript复制Prepare the reducer details, NO EDIT STATE DIRECTLY
export const reducers = (
state: StateType,
actionData: ActionPayloadDataType,
): StateType => {
switch (actionData.type) {
case ActionType.setAttrA:
return {
...state,
attributeA: {
...state.attributeA,
...actionData.payload,
},
};
case ActionType.setAttrB:
return {
...state,
attributeB: {
...state.attributeB,
...actionData.payload,
},
};
case ActionType.add:
return {
...state,
num: state.num 1,
};
case ActionType.reduce:
return {
...state,
num: state.num - 1,
};
default:
return state;
}
};
Create Provider
代码语言:javascript复制Create a HOC for state provider
export const AppContext = createContext<{
state: StateType;
dispatch: React.Dispatch<ActionPayloadDataType>;
}>({
state: initialState,
dispatch: () => null,
});
/**
* @name StateProvider
* @description A HOC to wrap root components for global state manage
*/
export const StateProvider: React.FC = ({ children }) => {
const [state, dispatch] = useReducer(reducers, initialState);
return (
<AppContext.Provider value={{ state, dispatch }}>
{children}
</AppContext.Provider>
);
};
Wrap your root Component
代码语言:javascript复制const App: React.FC = () => (
<StateProvider>
<RootComponent/>
</StateProvider>
);
Access Context in any of child components
代码语言:javascript复制Now you can use it
const Camera: React.FC = () => {
const { state, dispatch } = useContext(AppContext);
return (
<div>
{state.num}
<button onClick={dispatch({
type: ActionType.add
})}/>
<button onClick={dispatch({
type: ActionType.setAttrB,
payload: {
propertyB1: 'dispatch this action to set property B1'
},
})}/>
</div>
);
};
export default Camera;