You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Redux新手求助:如何从异步Action的Reducer中取回数据

How to Retrieve Async Data in Redux Reducer

Hey there! Since you're new to Redux, let's walk through how to fix this and get your user data into the reducer properly. The core issue here is that plain Redux doesn't handle async actions out of the box—right now you're dispatching an action with a Promise as the payload, but the reducer will just get the Promise object itself, not the resolved data once the request finishes.

Let's Fix This Step by Step

1. Use Redux Thunk Middleware

Redux Thunk is the simplest middleware for handling async actions, perfect for beginners. It lets you write action creators that return functions (instead of plain objects) so you can handle async logic, then dispatch actions once the Promise resolves.

First, install it if you haven't already:

npm install redux-thunk

Then add it to your Redux store setup:

import { createStore, applyMiddleware } from 'redux';
import thunk from 'redux-thunk';
import rootReducer from './your-reducer-file';

const store = createStore(rootReducer, applyMiddleware(thunk));

2. Refactor Your mapDispatchToProps

Instead of dispatching an action with a Promise payload directly, we'll handle the async request inside a function, then dispatch success/failure actions once we have data (or an error):

const mapDispatchToProps = (dispatch) => {
  return {
    fetchUserList: () => {
      console.log('---In fetchUserList---');
      // Optional: Dispatch a "request started" action for loading states
      dispatch({ type: FETCH_USER_LIST_REQUEST });

      // Create your async request Promise
      const fetchUsers = new Promise((resolve, reject) => {
        let xhr = new XMLHttpRequest();
        console.log('xhr: ', xhr);
        xhr.open('GET', 'http://localhost:5000/data/fetch/users');
        
        xhr.onload = () => {
          if (xhr.status >= 200 && xhr.status < 300) {
            // Resolve with parsed JSON data
            resolve(JSON.parse(xhr.responseText));
          } else {
            reject(new Error(xhr.statusText));
          }
        };
        
        xhr.onerror = () => reject(new Error('Network request failed'));
        xhr.send(); // Don't forget to send the request!
      });

      // Handle Promise resolution/rejection
      fetchUsers
        .then(userData => {
          // Dispatch success action with the actual user data
          dispatch({ type: FETCH_USER_LIST_SUCCESS, payload: userData });
        })
        .catch(error => {
          // Dispatch failure action with error message
          dispatch({ type: FETCH_USER_LIST_FAILURE, payload: error.message });
        });
    }
  };
};

3. Update Your Reducer to Handle the New Actions

Now your reducer can listen for the success action and grab the data from action.payload:

// Define initial state with loading/error states (optional but recommended)
const initialState = {
  userList: [],
  isLoading: false,
  fetchError: null
};

const userReducer = (state = initialState, action) => {
  switch (action.type) {
    case FETCH_USER_LIST_REQUEST:
      return {
        ...state,
        isLoading: true,
        fetchError: null
      };
    case FETCH_USER_LIST_SUCCESS:
      return {
        ...state,
        isLoading: false,
        userList: action.payload // Here's your resolved user data!
      };
    case FETCH_USER_LIST_FAILURE:
      return {
        ...state,
        isLoading: false,
        fetchError: action.payload
      };
    default:
      return state;
  }
};

export default userReducer;

4. Access the Data in Your Component

Use mapStateToProps to pull the user data (and loading/error states) from the store into your component:

const mapStateToProps = (state) => {
  return {
    users: state.userReducer.userList, // Match your reducer's key in the root reducer
    isLoading: state.userReducer.isLoading,
    fetchError: state.userReducer.fetchError
  };
};

// Connect both functions to your component
export default connect(mapStateToProps, mapDispatchToProps)(YourComponent);

Why Your Original Code Didn't Work

Plain Redux reducers are pure, synchronous functions. When you dispatched the action with a Promise payload, the reducer ran immediately—before the Promise resolved. That means the reducer got the Promise object, not the user data you wanted. Redux Thunk solves this by letting you delay dispatching the final action until the async work is done.

内容的提问来源于stack exchange,提问作者HVenom

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 07:38:47