https://github.com/bexic/react-without-redux
import React, {
createContext,
useContext,
useReducer,
useCallback
} from 'react';
import { IContextProps } from 'common/types';
import { asyncer } from 'store/middlewares';
import mainReducer, { initialState } from 'store/reducers';
const GlobalStore = createContext({} as IContextProps);
export const useGlobalStore = () => useContext(GlobalStore);
export default function Provider({ children } : { children: React.ReactNode}) {
const [ state, dispatchBase ] = useReducer(mainReducer, initialState);
const dispatch = useCallback(asyncer(dispatchBase, state), []);
return (
<GlobalStore.Provider value={{ state, dispatch }}>
{children}
</GlobalStore.Provider>
);
}
export default function mainReducer(state: IState, action: object) {
// Receiving previous state here
const { items, login } = state;
// Receiving current state here
const currentState = {
items: itemsReducer.reducer(items, action),
login: loginReducer.reducer(login, action)
};
// Middlewares
logger(action, state, currentState);
return currentState;
}
const dispatch = useCallback(asyncer(dispatchBase, state), []);
return (
<GlobalStore.Provider value={{ state, dispatch }}>
{children}
</GlobalStore.Provider>
);
export function handleFetch() {
return async function (dispatch) {
try {
const data = await fetchItems()
// async
dispatch(setItems(data))
} catch (err) {
// sync
dispatch(error(err))
}
}
}
const useItems: any = () => {
const { state , dispatch } = useGlobalStore();
// List of Props
const { items } = state;
// List of Actions
const {
addItem,
resetItems,
completeItem
} = actions;
// Bind Actions
const itemsActions = bindActions({
addItem,
resetItems,
completeItem
}, dispatch);
return { items, ...itemsActions };
}
const TodoItem: React.FC<TodoItemProps> = props => {
const { completeItem } = useItems();
const handleComplete = () => {
completeItem(props.id);
}
return (
<div className='todo-item'>
<input
id={props.id.toString()}
type='checkbox'
checked={props.completed}
onChange={handleComplete} />
<label htmlFor={props.id.toString()} className={'todo-item-text' + (props.completed ? ' completed' : '')}>{props.text}</label>
</div>
);
}