如何在react redux的createSlice中使用hook

How to use hook in createSlice of react redux

react的createSlice中如何使用hooks将数据保存在localStorage中@reduxjs/toolkit 每当我更改主题时,我都想将数据保存在 localStorage 中。我知道这可以直接用 js 代码完成,我对 useLocalStorage 挂钩有问题。

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;

我尝试在更新数据之前调用挂钩,但出现错误

多项:

  1. Reducers 必须是纯函数。这意味着没有副作用,例如从 storeaction 以外的任何地方读取数据,也不会在任何地方写入数据。不允许使用 reducer 中的 localStorage。

  2. Hooks 只能从 React 组件调用 - 不能从一个组件之外的任何函数调用。好处是,如果您不希望 component-local 状态与您的本地商店“同步”(这里您不需要),那么您的所有代码都归结为 window.localStorage.setItem(key, JSON.stringify(valueToStore)); - 您不需要useState 这里的东西。

  3. 大多数人只是使用 redux-persist 将状态副本保存到 localStorage 并恢复它。它是高度可配置的,所以你也可以只保存它的一部分。

  4. 如果你想手动完成,你需要使用 一些 种中间件(因为这就是 Redux 中的副作用) - 我会建议使用 listener middleware of RTK 来查找存储更改并保存在侦听器中间件效果中。

解决方案 : 我已将数据保存部分移至 App.js 文件,我可以在其中监听设置更改并调用 useLocalStorage 挂钩

import { useEffect } from "react";
import { useRoutes } from "react-router-dom";
import { useSelector } from "react-redux";

import routes from "./routes";
import useLocalStorage from "./hooks/useLocalStorage";

const App = () => {
    const content = useRoutes(routes);
    const [, setSettings] = useLocalStorage("settings", {});

    const settings = useSelector(state => state.settings.value);


    useEffect(() => {
        setSettings(settings);
    }, [settings])


    return <>
        {content}
    </>
}


export default App