reactjs-store
A modern, simple, useful and powerful React.js store made with useContext and useReducer like reduxjs with redux-actions plugin support.
It is made to create a ready-to-go store in a moment by writing less code by calling just a createStore function.
Like redux the initial state is created by the reducers registered by you, the library call them with the @@PM_REACT_STORE_INIT
action.
Installation
Inside of your project install the library with the following command:
npm install --save @pietro-marino/reactjs-store
or
yarn add @pietro-marino/reactjs-store
How to use
Create the actions with the createAction
function, like this:
import createAction from "@pietro-marino/reactjs-store/createAction";
export const INCREMENT = "INCREMENT";
export const DECREMENT = "DECREMENT";
export const increment = createAction(INCREMENT);
export const increment = createAction(DECREMENT);
Now, you have three method to create all reducer you need:
- write it, for example:
const INITIAL_STATE = { value: 0 };
export default function myReducer(state = INITIAL_STATE, action) {
let newState = null;
const payload = action.payload;
switch(action.type) {
case 'increment':
newState = { value: state.value++ };
break;
case 'decrement':
newState = { value: state.value-- };
break;
default:
newState = state;
}
return newState;
}
- if the reducer only handles an action you can create it by calling the built-in function called
handleAction
:
import handleAction from "@pietro-marino/reactjs-store/handleAction";
const INITIAL_STATE = { value: 0 };
const myReducer = handleAction('increment', (state, action) => {
return { value: state.value++ };
}, INITIAL_STATE);
export default myReducer;
- to avoid using the switch you can use the
handleActions
function:
import handleActions from "@pietro-marino/reactjs-store/handleActions";
const INITIAL_STATE = { value: 0 };
function increment(state, action) {
return { value: state.value++ };
}
function decrement(state, action) {
return { value: state.value++ };
}
const myReducer = handleActions({
'increment': increment,
'decrement': decrement
}, INITIAL_STATE);
export default myReducer;
Finally, you can create the store and some utilities you need with createStore
function.
This function create for you:
-
the Provider component
-
the Consumer component
-
useStore hook to use state and the dispatcher within your functional component
const [state, dispatch] = useStore();
-
useSelector hook to extract a portion of the state
const [state, dispatch] = useSelector(state => state['key']);
-
useDispatch hook to extract only the dispatcher from useStore, if help you
const dispatch = useDispatch();
So, with only one line of code you can create them all, like this:
import createStore from "@pietro-marino/reactjs-store";
export const {
Provider,
Consumer,
useStore,
useSelector,
useDispatch
} = createStore(myReducer);
Last but not least, for example we use the store created above, in your application:
App.js
import React from "react";
import { Provider } from "wherever you have created your store";
export default function App () {
return (
<Provider>
<Counter />
</Provider>
);
}
Counter.js
import React from "react";
import { useStore } from "wherever you have created your store";
import { increment, decrement } from "wherever you have created your actions";
export default function Counter () {
const [state, dispatch] = useStore();
const incrementCount = dispatch(increment());
const decrementCount = dispatch(decrement());
return (
<div className="counter">
<div>
Count: <span>${state.value}</span>
</div>
<div className="counter-actions">
<button onClick={incrementCount}>+</button>
<button onClick={decrementCount}>-</button>
</div>
</div>
);
}
Advanced uses
You can combine actions to simplify the reducers:
import handleActions from "@pietro-marino/reactjs-store/handleActions";
import combineActions from "@pietro-marino/reactjs-store/combineActions";
const INITIAL_STATE = { value: 0 };
function increment(state, action) {
return { value: state.value++ };
}
function decrement(state, action) {
return { value: state.value++ };
}
function reset(state, action) {
return { value: 0 };
}
const myReducer = handleActions({
'increment': increment,
'decrement': decrement,
[combineActions("reset", "setZero")]: reset
}, INITIAL_STATE);
export default myReducer;
Combine reducers to a root reducer, like this:
import combineReducers from "@pietro-marino/reactjs-store/combineReducers";
const reducerOne = (state, action) => {};
const reducerTwo = (state, action) => {};
const reducerThree = (state, action) => {};
const rootReducer = combineReducers({
'one': reducerOne,
'two': reducertwo,
'three': reducerThree
});
import createStore from "@pietro-marino/reactjs-store";
export const {
Provider,
Consumer,
useStore,
useSelector,
useDispatch
} = createStore(myReducer);
// useful selectors
export const useOneSelector = () => useSelector(state => state['one']);
export const useTwoSelector = () => useSelector(state => state['two']);
export const useThreeSelector = () => useSelector(state => state['three']);
Examples
Inside the examples folder you can find a todo-app example that use this library.
License
@pietro-marino/reactjs-store is MIT licensed.