存储没有有效的缩减器.确保传递给combineReducers的参数是一个对象



我的ReactJSRedux-Toolkit有点问题

我想用global state代替Theme Switcher。这样我就可以在App.tsx中围绕我的整个项目包装一个Material UI主题。但我总是收到错误:Store does not have a valid reducer. Make sure the argument passed to combineReducers is an object whose values are reducers.

我的商店配置如下:

import { combineReducers, configureStore, getDefaultMiddleware } from '@reduxjs/toolkit';
import { TypedUseSelectorHook, useSelector } from 'react-redux';
import { applyMiddleware } from 'redux';
import { themeUiReducer } from './ui/themeSlice';
export const rootReducer = combineReducers({
data: combineReducers({
}),
ui: combineReducers({
theme: themeUiReducer
}),
});
export const store = configureStore({
reducer: rootReducer,
middleware: (getDefaultMiddleware) => [...getDefaultMiddleware()],
});
export type RootState = ReturnType<typeof store.getState>
export const useTypedSelector: TypedUseSelectorHook<RootState> = useSelector;

我的主题UIReducer看起来是这样的:

import { createEntityAdapter, createSlice, PayloadAction } from "@reduxjs/toolkit";
export interface IThemes {
themeMode: boolean | undefined,
useOs: boolean | undefined
}
const initialState: IThemes = {
themeMode: false,
useOs: false
}
const themeSlice = createSlice({
name: 'themeUI',
initialState: initialState,
reducers: {
setThemeMode: (state, action: PayloadAction<boolean | undefined>) => {
state.themeMode = action.payload;
},
setUseOs: (state, action: PayloadAction<boolean | undefined>) => {
state.useOs = action.payload;
},
},
extraReducers: {
}
})
export const { setThemeMode, setUseOs } = themeSlice.actions;
export const themeUiReducer = themeSlice.reducer;

我调度reducer的App.tsx文件的配置如下:

import React, { useCallback, useState } from 'react';
import './App.css';
import Layout from './components/Layout';
import { Route, Switch, Redirect, withRouter } from 'react-router-dom';
import { ThemeProvider, createTheme, useMediaQuery, CssBaseline } from '@mui/material';
import ThemeSwitcher from './theme/themeSwitcher';
import { useDispatch } from 'react-redux';
import { setThemeMode, setUseOs } from './store/ui/themeSlice';
function App() {
const dispatch = useDispatch();
// Get OS-level preference for dark mode
const prefersDarkMode: boolean | undefined = useMediaQuery("(prefers-color-scheme: dark)");
const [darkMode, setDarkMode] = useState<boolean | undefined>(prefersDarkMode);
const themeOption = (b: boolean) => (b ? "dark" : "light");
const theme = React.useMemo(
() =>
createTheme({
palette: {
mode: themeOption(darkMode!)
}
}),
[darkMode]
);
const toggleDarkMode = (checked: boolean | undefined) => {
if (checked === null)
setDarkMode(prefersDarkMode);
else setDarkMode(checked);
};
const dispatchTheme = useCallback(
(themeMode: boolean | undefined) => {
if(themeMode === null)
dispatch(setThemeMode(prefersDarkMode));
else
dispatch(setThemeMode(themeMode));
},
[dispatch]
);

return (
<ThemeProvider theme={theme}>
<CssBaseline />
<ThemeSwitcher useOs={false} themeChanger={dispatchTheme} />
<Layout>
<Switch>
<Route />
<Route />
<Route />
</Switch>
</Layout>
</ThemeProvider>
);
}
export default App;

因此,我稍后将在导航/页脚中使用ThemeSwitch,并通过全局状态查看用户的选择

您的错误消息告诉您要查找的位置:

Store没有有效的reducer确保参数通过to combine reducers是一个其值为reducers的对象

此处的问题是使用data状态的空对象调用combineReducers

export const rootReducer = combineReducers({
data: combineReducers({
// Here is the problem. It needs a reducer.
}),
ui: combineReducers({
theme: themeUiReducer
}),
});

由于您现在根本没有使用data属性,因此最简单的方法是将其从您的状态中删除。

export const rootReducer = combineReducers({
ui: combineReducers({
theme: themeUiReducer
}),
});

如果你想为未来的减速器提供一个占位符,你可以提供一个"占位符";无操作";减速器功能,它什么都不做。

export const rootReducer = combineReducers({
data: (state = null, action) => state,
ui: combineReducers({
theme: themeUiReducer
}),
});

最新更新