Redux中间件数据获取报错:Uncaught TypeError: Cannot read property 'type' of undefined
Hey there! Let's break down that frustrating error you're hitting with your Redux Epic middleware. That "Cannot read property 'type' of undefined" message almost always traces back to one core issue: your Epic isn't emitting valid Redux actions (or it's emitting nothing at all). Let's walk through the most common fixes and checks:
1. Make sure your Epic returns an Observable of actions
This is the #1 mistake I see. It's easy to forget the return statement, or fail to map your async results to a proper action object. For example:
❌ Wrong (missing return or action mapping)
const fetchDataEpic = (action$) => { action$.pipe( ofType('FETCH_DATA'), switchMap(() => fetch('/api/data') .then(res => res.json()) // Oops: no action returned here ) ); // Also missing return for the entire Observable chain! };
✅ Correct
const fetchDataEpic = (action$) => { return action$.pipe( ofType('FETCH_DATA'), switchMap(() => fetch('/api/data') .then(res => res.json()) .then(data => ({ type: 'FETCH_SUCCESS', payload: data })) .catch(err => ({ type: 'FETCH_FAILURE', payload: err.message })) ) ); };
2. Ensure every code branch returns an action
If your Epic has conditionals or error handlers, don't leave any path that returns undefined. For example, if you have a check for empty data, make sure you still dispatch an action (even a "NO_DATA" action) instead of silently failing.
❌ Wrong (missing fallback action)
.map(data => { if (data.length > 0) { return { type: 'DATA_LOADED', payload: data }; } // No return here → emits undefined })
✅ Correct
.map(data => { if (data.length > 0) { return { type: 'DATA_LOADED', payload: data }; } return { type: 'NO_DATA_AVAILABLE' }; }) // Or filter out empty data first .filter(data => data.length > 0) .map(data => ({ type: 'DATA_LOADED', payload: data }))
3. Verify your Epic Middleware setup
Double-check that you've properly configured redux-observable in your Redux store. If you forget to run the root Epic, you might get unexpected errors (though this is less likely to cause the "type" error specifically):
import { createEpicMiddleware } from 'redux-observable'; import rootEpic from './epics'; import rootReducer from './reducers'; const epicMiddleware = createEpicMiddleware(); const store = createStore( rootReducer, applyMiddleware(epicMiddleware) ); // Don't forget this line! epicMiddleware.run(rootEpic);
4. Debug with logging to find the undefined
Add a tap operator to your Epic's pipe to log what's flowing through the stream. This will help you pinpoint exactly where undefined is being introduced:
return action$.pipe( ofType('FETCH_DATA'), switchMap(() => fetch('/api/data').then(res => res.json())), tap(console.log), // Logs the value before mapping to action map(data => ({ type: 'FETCH_SUCCESS', payload: data })) );
If the tap logs undefined, your fetch call is returning nothing. If it logs valid data but you still get the error, check your map function to ensure it always returns an action object.
内容的提问来源于stack exchange,提问作者Lukáš Šálek

