0.0.1 • Published 4 years ago

react-use-reduxlike-reducer v0.0.1

Weekly downloads
4
License
MIT
Repository
github
Last release
4 years ago

REACT-USE-REDUXLIKE-REDUCER

NPM VERSION Dependencies

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.