custom-react-store v1.1.5
Custom React Store ·
This Custom React Store was created to be a light-weight alternative to using React-Redux library for medium to light weight app need and does not use any external libraries. The React app demonstrates a working example on how to use the custom react store. The react store uses the useContext and useReducer react hooks to implement an app state management system. Therefore your react app version should support this hooks as well.
Download Store
To get started, install the package with the command
npm install custom-react-store
Setup Store
To initialize the store, the combineStore
object is required. The combineStore
is an object of key-value pairs each for a specific store where the key is the storeName
(without space) and the value is an array of 3 elements i.e initialState
object, reducer
function and actions
object in this order for that store.
The initialState
object, reducer
function and actions
object could look as such:
// src/Store/counterStore.js
export const initialState = {
counter: 0,
};
export const reducer = (state, action) => {
switch (action.type) {
case "CHANGE":
return { ...state, counter: state.counter + action.payload };
case "RESET":
return { ...state, counter: 0 };
default:
return state;
}
};
export const actions = {
change: (payload) => ({ type: "CHANGE", payload }),
reset: () => ({ type: "RESET" }),
};
This is a practical example of inititial State object, reducer function and action object.
The store can combine different states as long as the required data for each state is provided. The combine store can looks as such,
// src/Store/index
import * as counterStore from "counterStore.js"
/**
* The format for combining state is as follows:
*
* { [stateName: string]: [ initialState: object, stateReducer: function, stateActions: { [ actionName: string ]: function } ] }
*
* An example is shown below:
*/
const combineStore = {
CounterStore: [counterStore.InitialState, counterStore.reducer, counterStore.actions],
StoreName: [InitialState, storeReducer, storeActions], // For explanation purposes only. Replace with your store name
};
export default combineStore;
Here is a practical example of combineStore.
Connect Store
To use the store, it is neccessary to import the StoreProvider
component and wrap it with the root component or a specific component. The StoreProvider
requires an initStore
props with the combineStore
object as it's value. This will be used to initialise and expose the store to the children components. An example is provided below
// src/index.js
import React from "react";
import ReactDOM from "react-dom";
import App from "./App";
// Imports the combine store object
import CombineStore from "./Store/index";
// Imports the store provider
import { StoreProvider } from "custom-react-store";
// Wrap the App component with the store provider and provide the initStore props with the combine store to initialize and expose the store to the app.
ReactDOM.render(
<StoreProvider initStore={CombineStore}>
<App />
</StoreProvider>,
document.getElementById("root")
);
A practical example could be could be found in the ./src/index.js
Use Store
Any child of the StoreProvider
gets access to the store through the useStore
hook. This will return the store object of key-value pairs each for a given store where the key is the storeName
and the value is an array of 3 elements i.e currentState
object, dispatch
function and the actions
object in this order.
Note that a dispatch function is bound to the reducer function of its store only.
// src/App.js
import { useStore } from "custom-react-store";
const App = () => { // App or any other component gets access to the store via useStore hook
const store = useStore(); // returns the store
const { CounterStore } = store; // access a specific store
const [ counterState, counterDispatch, counterActions] = CounterStore; // access the current store state, dispatch function for the state and the state action object
const { counter } = counterState; // access a data of the store's current state
const { change, reset } = counterActions; // access an action from the actions object
return (
<div>
{/* using (displaying) the data from the state. Data get's updated when it's value changes */}
<h1>{ counter }</h1>
{/* dispatching changes to the counter store state */}
<button onClick={() => counterDispatch(change(+1))}>+</button>
<button onClick={() => counterDispatch(reset())}>reset</button>
<button onClick={() => counterDispatch(change(-1))}>-</button>
</div>
);
};
A practical example can be found here: display store data and dispatch action to store