React+Redux项目报错:DonationCandidateAPI.fetchAll不是函数
报错信息
Uncaught TypeError: api__WEBPACK_IMPORTED_MODULE_0_.default.DonationCandidateAPI.fetchAll is not a function
at DonationCandidateActions.js:10:1
at index.js:16:1
at boundActionCreators. [as fetchAllDonationCandidates] (bindActionCreators.js:8:1)
at DonationCandidatesComponent.js:8:1
at commitHookEffectListMount (react-dom.development.js:23150:1)
at commitPassiveMountOnFiber (react-dom.development.js:24926:1)
at commitPassiveMountEffects_complete (react-dom.development.js:24891:1)
at commitPassiveMountEffects_begin (react-dom.development.js:24878:1)
at commitPassiveMountEffects (react-dom.development.js:24866:1)
at flushPassiveEffectsImpl (react-dom.development.js:27039:1)
核心错误原因
你的API模块中,DonationCandidateAPI是一个函数,而非直接包含方法的对象。当前action中直接尝试访问api.DonationCandidateAPI.fetchAll,相当于访问函数的属性,自然会报错。
修复步骤
1. 修改Action中的API调用方式
在DonationCandidateActions.js里,需要先执行DonationCandidateAPI函数,再调用fetchAll方法:
import api from './api'; export const ACTION_TYPE = { CREATE: "CREATE", UPDATE:"UPDATE", DELETE:"DELETE", FETCH_ALL:"FETCH_ALL" } export const fetchAll = () => dispatch => { // 先执行DonationCandidateAPI函数,获取包含方法的对象 api.DonationCandidateAPI().fetchAll() .then( response => { dispatch( { type:ACTION_TYPE.FETCH_ALL, payload:response.data } ) }, ) .catch(err => console.log(err)) }
2. 修复Reducer的逻辑错误
你的Reducer中存在致命问题:switch语句判断的是整个actions对象,而非actions.type。这会导致永远匹配不到ACTION_TYPE.FETCH_ALL,即使API调用成功,状态也不会更新。修改如下:
import {ACTION_TYPE} from "../actions/DonationCandidateActions"; const initialState = { list:[] } export const DonationCandidateReducer = (state=initialState, action) => { // 这里要判断action.type,不是整个action对象 switch (action.type) { case ACTION_TYPE.FETCH_ALL: return { ...state, list:[...action.payload] } default: return state; } }
3. 可选:优化API模块写法
如果不想每次调用都执行函数,可以调整API模块的导出方式,直接导出包含方法的对象:
import axios from 'axios'; const baseurl = "http://localhost:42426/api/"; const url = baseurl + "donationcandidate"; export const DonationCandidateAPI = { fetchAll: () => axios.get(url), fetchById: (id) => axios.get(`${url}/${id}`), create: (newRecord) => axios.post(url,newRecord), update: (id,updatedRecord) => axios.put(`${url}/${id}`, updatedRecord ), delete: (id) => axios.delete(`${url}/${id}`) } // 此时Action中的调用方式改为: // import { DonationCandidateAPI } from './api'; // DonationCandidateAPI.fetchAll()
额外提示
- 检查API请求URL:
fetchById、update、delete方法中,原写法url+id会导致URL缺少斜杠(比如变成donationcandidate123),建议用模板字符串${url}/${id}拼接,避免404错误。 - 确保后端API服务正常运行在
http://localhost:42426。
内容的提问来源于stack exchange,提问作者Usman

