Skip to content

Instantly share code, notes, and snippets.

@bagus2x
Created April 21, 2021 07:19
Show Gist options
  • Select an option

  • Save bagus2x/4dd57bc9f484b4cc415efdc0b00178c3 to your computer and use it in GitHub Desktop.

Select an option

Save bagus2x/4dd57bc9f484b4cc415efdc0b00178c3 to your computer and use it in GitHub Desktop.
import React, { createContext, Dispatch, useContext, useMemo } from 'react';
interface ActionsT {
INCREMENT: string;
DECREMENT: string;
}
export const Actions: ActionsT = {
INCREMENT: 'INCREMENT',
DECREMENT: 'DECREMENT'
};
export type ActionType = {
type: string;
};
interface State {
count: number;
}
const initialState = {
count: 0
};
function reducer(state = initialState, action: ActionType) {
switch (action.type) {
case Actions.INCREMENT:
return { count: state.count + 1 };
case Actions.DECREMENT:
// need to cast type herer
return { count: state.count - 1 };
default:
return state;
}
}
export const Store = createContext<{
state: State;
dispatch: Dispatch<ActionType>; //action type here
}>({
state: initialState,
dispatch: () => null
});
export function StoreProvider({ children }: JSX.ElementChildrenAttribute): JSX.Element {
const [state, dispatch] = React.useReducer(reducer, initialState);
const value = useMemo(() => ({ state, dispatch }), [state, dispatch]);
return <Store.Provider value={value}>{children}</Store.Provider>;
}
const Child = () => {
const { state, dispatch } = useContext(Store);
return (
<div>
<h1>{state.count}</h1>
<button onClick={() => dispatch({ type: 'INCREMENT' })}>Inc</button>
<button onClick={() => dispatch({ type: 'DECREMENT' })}>Dec</button>
</div>
);
};
const AnotherChild = () => {
const { state } = useContext(Store);
return <div>{state.count}</div>;
};
const App = () => {
return (
<StoreProvider>
<AnotherChild />
<Child />
</StoreProvider>
);
};
export default App;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment