How to use hooks to save data in localStorage in createSlice of react @reduxjs/toolkit When ever I change the theme I want to save the data in localStorage. I know this can done directly with js code with I am having issue with useLocalStorage hook.
import { createSlice } from "@reduxjs/toolkit";
import useLocalStorage from "../hooks/useLocalStorage";
const initialState = {
theme: true
}
const [settings, setSettings] = useLocalStorage("settings", initialState);
export const settingsSlice = createSlice({
name: "theme",
initialState: { value: initialState },
reducers: {
setSettings: (state, action) => {
state.value = action.payload;
},
toggleTheme: (state) => {
const temp = { ...state.value, theme: !state.value.theme };
//save in localStorage
setSettings(temp);
state.value = temp;
},
},
});
export const { toggleTheme } = settingsSlice.actions;
export default settingsSlice.reducer;
import { useState } from "react";
function useLocalStorage(key, initialValue) {
const [storedValue, setStoredValue] = useState(() => {
try {
const item = window.localStorage.getItem(key);
return item ? JSON.parse(item) : initialValue;
} catch (error) {
console.log(error);
}
});
const setValue = (value) => {
try {
window.localStorage.setItem(key, JSON.stringify(valueToStore));
} catch (error) {
console.log(error);
}
};
return [storedValue, setValue];
}
export default useLocalStorage;
I tried to call the hook before updating my data but I got error
Multiple things:
Reducers have to be pure functions. That means no side effects like reading data from anywhere except from store
and action
and no writing data anywhere, too. You are not allowed to use localStorage from a reducer.
Hooks can only be called from React components - not any function outside of one. The good thing is that if you do not want a component-local state "synced" with your local store (here you don't), all your code here boils down to window.localStorage.setItem(key, JSON.stringify(valueToStore));
- you don't need the useState
stuff here.
Most people just use redux-persist to save a copy of state to localStorage and restore that. It is highly configurable, so you can also only save a portion of it.
If you want to do it by hand, you need to use some kind of middleware (since that is where side effects belong in Redux) - I would recommend using the listener middleware of RTK to look for store changes and saving in a listener middleware effect.