6

How to Create a Custom State Management Library With React Hooks and Context API

 1 year ago
source link: https://hackernoon.com/how-to-create-a-custom-state-management-library-with-react-hooks-and-context-api
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

In this article, I will introduce the React Context API for state management and create a similar solution as Redux without using a third-party library.

React Context API

It’s actually not a new idea. Context API has been a part of React for a long time, but only in an experimental state.

Since React 16.3.0, it’s officially stable and ready to use in production.

Without Further Ado, Here Are the Steps

Step: 1 Creating Provider and connect function (same as react-redux connect and Provider) using useReducer, createContext & useContext.

import React, { useReducer, createContext, useContext } from "react";
const initialState = {};
// Create App Context
export const Context = createContext(initialState);
export const Provider = ({ children, reducers}) => {
    const defaultState = reducers(undefined, initialState);
    if (defaultState === undefined) {
       throw new Error("reducer's should not return undefined");
    }
    const [state, dispatch] = useReducer((_state, _action) => {
        return reducers(_state, _action);
    }, defaultState);
    return (
        <Context.Provider value={{ state, dispatch }}>
            {children}
        </Context.Provider>
    );
};
export const useDispatch = () => useContext(Context).dispatch;
export const useSelector = (callback) => {
  const state = { ...useContext(Context).state };
  return callback ? callback(state) : state;
};

Step: 2 Connect react app to the above-created Provider.

const actionMap = {
  INCREMENT: (state, action) => ({ ...state, count: state.count + 1 }),
  DECREMENT: (state, action) => ({ ...state, count: state.count - 1 }),
};

const countReducer = (state = { count: 0 }, action) => {
    const exec = actionMap[action.type];
    return exec ? exec(state, action) : state;
};


const reducers = { countReducer };
const App = () => (
    <Provider reducers={reducers}>
        <Component />
    </Provider>
);

Step: 3 Connect component to react Context.

const Component = () => {
  const dispatch = useDispatch();
  const { count } = useSelector((state) => state.countReducer);
  return (<h3>Context State: {count} </h3>)
}

Live Demo: Here

Bonus Tip

export const combineReducers = (reducers) => {
  const entries = Object.entries(reducers);
  return (state = {}, action) => {
    return entries.reduce((_state, [key, reducer]) => {
      _state[key] = reducer(state[key], action);
      return _state;
    }, {});
  };
};

Thank you for reading 😊

Got any additional questions? please leave a comment.


Must Read If You Haven't

Javascript: No More callbacks, Use Promisify to Convert Callback to Promise

Creating a Custom Hook for Fetching Asynchronous Data: useAsync Hook with Cache

Javascript Promise Methods with polyfill example: A Cheat Sheet for Developer


Catch me on: Github, Twitter, LinkedIn, Medium, Dev.to, Blogspot, Hashnode, Stackblitz


Also published here


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK