Next.js使用@reduxjs/toolkit时useSelector返回undefined问题求解
问题原因分析
1. store注册reducer时导入错误
你在store.js中导入的detectDevice是slice生成的action creator,不是你导出的reducer。store里把action当成reducer注册后,state.isMobile对应的内容根本不是你定义的初始状态结构,自然读取state.isMobile.value返回undefined。
2. reducer定义不接收传入参数
你定义的detectDevice reducer没有处理payload参数,只是固定翻转原有value的值,你在dispatch时传入的true/false完全不会生效。
3. useEffect打印时机错误
你在dispatch之后立刻打印本次渲染拿到的size,Redux状态更新后需要触发组件重新渲染才能拿到新值,本次渲染的size始终是更新前的值。
4. useEffect缺少依赖数组
当前useEffect没有传入依赖数组,每次组件渲染都会重新执行,会导致不必要的重复dispatch,甚至触发无限循环。
修正后的代码
1. reducer文件(device.js)
import { createSlice } from "@reduxjs/toolkit"; export const deviceSlice = createSlice({ name: "isMobile", initialState: { value: false, }, reducers: { // 增加payload参数,直接用传入的值设置状态 detectDevice: (state, action) => { state.value = action.payload; }, }, }); export const { detectDevice } = deviceSlice.actions; export default deviceSlice.reducer;
2. store.js文件
import { configureStore } from "@reduxjs/toolkit"; // 导入默认导出的reducer,不要加花括号 import deviceReducer from "./device"; export default configureStore({ reducer: { isMobile: deviceReducer, }, });
3. 首页index.js文件
import Head from "next/head"; import Nav from "../components/nav/Nav"; import { useEffect } from "react"; import { useSelector, useDispatch } from "react-redux"; import { detectDevice } from "../redux/device"; export default function Home() { const dispatch = useDispatch(); const isMobile = useSelector((state) => state.isMobile.value); // 仅组件挂载时执行一次设备判断 useEffect(() => { dispatch(detectDevice(window.innerWidth < 576)); }, [dispatch]); // 监听isMobile变化打印最新值 useEffect(() => { console.log(isMobile); }, [isMobile]); return ( <div> <Head> <title>Create Next App</title> <meta name="description" content="Generated by create next app" /> <link rel="icon" href="/favicon.ico" /> </Head> <Nav /> </div> ); }
内容的提问来源于stack exchange,提问作者Hashim Hashimli
相关产品推荐
相关产品推荐

