0.0.1 • Published 4 years ago
react-use-reduxlike-reducer v0.0.1
REACT-USE-REDUXLIKE-REDUCER
A factory to create a React useReducer
Hook with Redux-like reducers and actions.
Available as NPM package.
Why?
By default, useReducer
does not provide an easy way to dispatch asynchronous actions or chaining multiple dispatches from a single action.
react-use-reduxlike-reducer
is a package that exposes a factory method to create a wrapper around the useReducer
hook that will make your actions behave like actions from React Redux or React Saga. This package is built with TypeScript and is completely typesafe.
import React from 'react';
import { createReducerFactory } = from 'react-use-reduxlike-reducer';
const fetchMyData = async (dispatch) => {
dispatch({ type: 'LOADING', payload: true });
const myData = await myApiClient.getData();
dispatch({ type: 'NEW_DATA', payload: myData });
dispatch({ type: 'LOADING', payload: false });
};
const reducer = (state, action) => {
switch (action.type) {
case 'LOADING': return { ...state, loading: action.payload };
case 'NEW_DATA': return { ...state, data: action.payload };
default: return state;
}
};
const initialState = { loading: false, data: [] };
const useMyReducer = createReducerFactory(reducer, initialState);
const MyComponent = () => {
const [state, dispatch] = useMyReducer();
return (
<>
{state.loading ? <div>Loading, please wait!</div> : null }
<ul>
{state.data.map((item, i) => (<li key={i}>{item}</li>))}
</ul>
<button
disabled={state.loading}
onClick={() => dispatch(fetchMyData)}>
load data
</button>
</>
);
}
export default MyComponent;
The second argument of an action is a method to get your current state when the action dispatch. This object is immutable.
const myAction = async (dispatch, getState) => {
const stateBeforeDispatch = getState();
dispatch({ ... });
const stateAfterDispatch = getState();
assert(stateBeforeDispatch === stateAfterDispatch);
};
See the examples folder for an use case using reducer + context Hooks in combination with TypeScript.