React+Redux应用useSelector获取state为undefined问题求助
问题:React-Redux中useSelector获取state返回undefined,store.getState()却正常
我用React+Redux+Router开发了一个汽车交易小应用,核心是展示全部车辆和收藏车辆组件。车辆项的添加/移除收藏功能逻辑正常,通过Redux DevTools和store.getState()的console.log能确认store里的state可以正常增删数据。
但用useSelector(state => state.move_cars)替代store.getState()时出问题:store.getState()能正常筛选收藏车辆,useSelector拿到的selected却是undefined。move_cars是唯一的reducer,不知道为啥拿不到数组类型的state。
相关代码
收藏组件(Favorites)
import React from 'react' import style from "../components/styles/favorites.module.css"; import {store} from "../index.js" import {move_cars} from "../" import {useDispatch, useSelector} from "react-redux"; import {remove_car} from "../a_actions"; import cars from "../data/info/data.js"; const Favorites = () => { const images = require.context("../data/img", true); const dispatch = useDispatch(); const selected = useSelector(state => state.move_cars); // const selected = store.getState(); const handler = (e) => { // console.log("testing console from favs", selected); console.log("testing console from favs", selected); dispatch(remove_car(e)); } return ( <> <div className={style.container}> {cars.map( x => { // const checker = selected.some(item => item === x.Id); if(true){ return ( <div className={style.car}> <p className={style.textcartitle}> {x.Brand} </p> <p className={style.textcar}>{Object.keys(x)[0]}: {x.Model} </p> <p className={style.textcar}>{Object.keys(x)[1]}: {x.Hp} cv </p> <p className={style.textcar}>{Object.keys(x)[3]}: {x.Year} </p> <p className={style.textcar}>{Object.keys(x)[4]}: {x.City} </p> <p className={style.textcar}>{Object.keys(x)[5]}: {x.Km} </p> <img src={images(`${x.src}`)} className={style.imgin} alt="test"/> <div value={x.Id} className={style.buttonfav} onClick={() => handler(x.Id)}>Remove from favorites</div> </div> ); } })} </div> </> ) } export default Favorites
Reducer代码
let initialState = []; export const move_cars = (state = initialState, action) => { switch(action.type){ case "add_car": const varcheck = state.some((x) => x === action.payload); if (!varcheck) { return [...state, action.payload]; } case "remove_car": return state.filter((car_id) => car_id !== action.payload ) default: return state; } }
主入口index.js代码
import React from 'react'; import ReactDOM from "react-dom/client"; import './index.css'; import App from './App'; import {Provider} from "react-redux"; import {move_cars} from "./a_reducers"; import {createStore} from "redux"; export const store = createStore( move_cars, window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__() ); const root = ReactDOM.createRoot(document.getElementById('root')); root.render( <React.StrictMode> <Provider store={store}> <App /> </Provider> </React.StrictMode> );
解答
问题出在两个核心点:
1. useSelector的取值路径错误
你直接用createStore(move_cars)创建了store,这意味着根state就是move_cars reducer管理的数组,而非包含move_cars属性的嵌套对象。因此正确的取值方式是直接获取state本身:
const selected = useSelector(state => state); // 直接取根state,即收藏的id数组
2. Reducer的switch case逻辑漏洞
add_car分支里没有在return后终止逻辑,也没有处理“车辆已存在”的情况。当执行完add_car的return后,代码会继续进入remove_car分支,导致刚添加的id被立刻过滤,state出现异常。修复后的reducer:
let initialState = []; export const move_cars = (state = initialState, action) => { switch(action.type){ case "add_car": const varcheck = state.some((x) => x === action.payload); if (!varcheck) { return [...state, action.payload]; } // 车辆已存在时直接返回原state,避免执行后续分支 return state; case "remove_car": return state.filter((car_id) => car_id !== action.payload ) default: return state; } }
额外优化:恢复收藏车辆的渲染逻辑
当前代码注释了收藏判断,直接渲染所有车辆,应恢复逻辑只展示收藏的车辆:
{cars.map( x => { const checker = selected.some(item => item === x.Id); if(checker){ return ( <div className={style.car}> {/* 车辆信息内容 */} </div> ); } return null; // 非收藏车辆不渲染 })}
内容的提问来源于stack exchange,提问作者bashop
相关产品推荐
相关产品推荐

