Redux调用第三方fetch API获取数据时出现reducer和map报错如何解决
Redux 异步请求功能修复方案
错误1:Store does not have a valid reducer 修复
原因
- reducer 导入路径不匹配:你在
combineReducer.js中导出了合并后的reducer,但在index.js中导入路径写的是./reducers,如果你的combineReducer.js存放在src/reducers目录下,需要将文件名改为index.js才能直接导入目录,否则需要写全路径./reducers/combineReducer - 缺少异步中间件配置:你写的是异步action,原生Redux不支持直接传入函数类型的action,需要安装配置
redux-thunk中间件
修复代码
首先安装依赖:npm install redux-thunk
修改 index.js 中store创建逻辑:
import React from 'react'; import ReactDOM from 'react-dom'; import App from './App'; import reportWebVitals from './reportWebVitals'; import { Provider } from "react-redux"; import { createStore, applyMiddleware, compose } from "redux"; import thunk from 'redux-thunk'; import reducer from './reducers'; // 确保这个路径对应你reducer文件的实际位置 const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose; const store = createStore(reducer, composeEnhancers(applyMiddleware(thunk))); ReactDOM.render( <Provider store={store}> <App /> </Provider>, document.getElementById('root') ); reportWebVitals();
错误2:Uncaught TypeError: Cannot read properties of undefined (reading 'map') 修复
原因
- action 逻辑错误:
useDispatch是React组件Hook,不能在action函数中调用,thunk异步action会自动接收dispatch作为参数 - reducer 逻辑错误:初始state设为了对象(没有map方法),且接收到
GET_DATAaction时没有把接口返回的数组存入state - 组件未触发请求:没有调用
getData发起接口请求,且没有做数据加载中的兜底判断
修复代码
修改 action.js
export const getData = () => async(dispatch) => { await fetch('https://api.instantwebtools.net/v1/airlines', { method : 'GET' }).then( res => res.json() ).then( data => dispatch({ type : "GET_DATA", payload : data }) ); };
修改 reducer.js
// 初始值改为空数组,匹配接口返回的数组类型 const FetchData = (state = [], action) => { switch (action.type) { case "GET_DATA": // 把接口返回的数据存入state return action.payload; default: return state; } }; export default FetchData;
修改 screen.jsx
import React, { useEffect } from "react"; import { useSelector, useDispatch } from "react-redux"; import { getData } from './action'; // 替换为你实际的action文件导入路径 const Screen = () => { const dispatch = useDispatch(); const airlineList = useSelector(state => state.get); // 组件挂载时发起请求 useEffect(() => { dispatch(getData()); }, [dispatch]); return ( <div> {/* 加可选链判断,避免数据未加载完成时报错 */} {airlineList?.map((item, index) => ( <ul key={index}> <li>{item.name}</li> </ul> ))} </div> ); }; export default Screen;
内容的提问来源于stack exchange,提问作者coolhack7
相关产品推荐
相关产品推荐

