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

Redux Toolkit异步Action始终处于pending状态问题求助

问题解决:Redux Toolkit Async Thunk 始终处于 Pending 状态的修复方案

以下是针对你的问题的分步排查和修复方法:

1. 确保 Async Thunk 返回可正确 Resolve 的 Promise

Async Thunk 依赖返回的 Promise 来判断异步操作是否完成,如果未正确返回 Promise 或 Promise 未 resolve,action 会一直处于 pending 状态。

错误示例(未返回 Promise):

export const scrapeProjects = createAsyncThunk(
  'projects/scrape',
  async () => {
    // 仅打印数据但未返回 Promise,导致 Async Thunk 无法感知操作完成
    axios.get('/api/scrape').then(res => console.log(res.data))
  }
);

正确示例:

export const scrapeProjects = createAsyncThunk(
  'projects/scrape',
  async () => {
    // 等待请求完成并返回数据,Async Thunk 会自动处理 Promise 状态
    const response = await axios.get('/api/scrape');
    console.log(response.data);
    return response.data; // 返回的数据会作为 fulfilled action 的 payload
  }
);

2. 在 Slice 中正确处理 Fulfilled 状态

必须在 Slice 的 extraReducers 中定义 fulfilled 分支,将返回的数据存入 projectState 数组:

import { createSlice } from '@reduxjs/toolkit';
import { scrapeProjects } from './yourAsyncThunkFile';

const projectsSlice = createSlice({
  name: 'projects',
  initialState: {
    projectState: [],
    status: 'idle',
    error: null
  },
  reducers: {},
  extraReducers: (builder) => {
    builder
      .addCase(scrapeProjects.pending, (state) => {
        state.status = 'loading';
      })
      .addCase(scrapeProjects.fulfilled, (state, action) => {
        state.status = 'succeeded';
        // 将爬取的数据添加到 projectState 数组(或根据需求替换数组)
        state.projectState = [...state.projectState, ...action.payload];
      })
      .addCase(scrapeProjects.rejected, (state, action) => {
        state.status = 'failed';
        state.error = action.error.message;
      });
  }
});

export default projectsSlice.reducer;

3. 验证后端 API 的响应逻辑

后端必须确保正确返回 HTTP 2xx 状态码和 JSON 格式数据,否则前端请求会挂起或进入 rejected 状态:

后端示例(Express):

app.get('/api/scrape', async (req, res) => {
  try {
    const scrapedData = await yourScrapingFunction();
    console.log(scrapedData); // 你已确认此处能输出数据
    res.status(200).json(scrapedData); // 必须用 res.json 返回数据给前端
  } catch (error) {
    res.status(500).json({ error: error.message });
  }
});

如果后端仅打印数据但未响应前端,前端请求会一直处于 pending,导致 Async Thunk 无法进入 fulfilled 状态。

4. 在 React 组件中调试 Dispatch 结果

使用 unwrap() 方法可以直接获取 Async Thunk 的 Promise 结果,快速定位是 fulfilled 还是 rejected:

import { useDispatch, useSelector } from 'react-redux';
import { scrapeProjects } from './yourAsyncThunkFile';

function ScraperComponent() {
  const dispatch = useDispatch();
  const { projectState, status, error } = useSelector(state => state.projects);

  const handleScrape = async () => {
    try {
      // 用 unwrap() 直接获取异步结果
      const data = await dispatch(scrapeProjects()).unwrap();
      console.log('爬取完成,数据:', data);
    } catch (err) {
      console.log('爬取失败:', err);
    }
  };

  return (
    <div>
      <button onClick={handleScrape} disabled={status === 'loading'}>
        {status === 'loading' ? '爬取中...' : '开始爬取'}
      </button>
      {error && <p style={{color: 'red'}}>{error}</p>}
    </div>
  );
}

5. 确认 Store 配置正确

确保 Store 已正确注册项目的 Slice Reducer:

import { configureStore } from '@reduxjs/toolkit';
import projectsReducer from './projectsSlice';

export const store = configureStore({
  reducer: {
    projects: projectsReducer, // 必须注册对应的 reducer
  },
});

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.25 05:15:44