useLocalStorageReducer
iamsolankiamit opened this issue · 0 comments
iamsolankiamit commented
Reducer with state synced with localStorage. Would be great for syncing state between tabs and sessions.
Basic initial Implementation would look like this
import React, { useReducer, useEffect } from "react";
import { render } from "react-dom";
import useLocalStorage from '@rehooks/local-storage';
function useLocalStorageReducer({ reducerKey, transformer }, reducer, initialState, initialAction) {
let localState = useLocalStorage(reducerKey);
if (localState) {
localState = JSON.parse(localState);
localState = transformer(localState);
} else {
localState = initialState;
}
const [state, dispatch] = useReducer(reducer, localState, initialAction);
useEffect(
() => {
localStorage.setItem(reducerKey, JSON.stringify(state));
},
[state]
);
return [state, dispatch];
}
const initialState = { count: 0 };
function reducer(state, action) {
switch (action.type) {
case "reset":
return { count: action.payload };
case "increment":
return { count: state.count + 1 };
case "decrement":
return { count: state.count - 1 };
default:
return state;
}
}
function transformer(state) {
return { ...state, count: parseInt(state.count) };
}
function Counter({ initialCount }) {
const [state, dispatch] = useLocalStorageReducer(
{ reducerKey: "counter", transformer },
reducer,
initialState
);
return (
<div>
Count: {state.count}
<button onClick={() => dispatch({ type: "reset", payload: initialCount })}>Reset</button>
<button onClick={() => dispatch({ type: "increment" })}>+</button>
<button onClick={() => dispatch({ type: "decrement" })}>-</button>
</div>
);
}
function App() {
let name = useLocalStorage("name");
return (
<div>
<h1>{name}</h1>
<Counter initialCount={0} />
</div>
);
}
Not sure about one thing, this won't update the reducerState once it is mounted. Need to investigate that.