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

React TypeScript中useReducer处理Promise的问题求助

问题分析与解决方案

核心问题

  1. Reducer是纯函数,不能直接处理异步逻辑
    你在reducer的load分支里直接调用loadTodos(),但loadTodos是异步函数,返回的是Promise对象而非实际todo数据。此时[...data]是在展开Promise,不是真实数据,导致状态更新错误。

  2. 异步代码执行顺序导致外部取值为空
    你尝试的then外部console.log(myState)为空,是因为JavaScript异步执行机制:同步代码(console.log)会优先于then里的异步回调执行,此时异步请求还没完成,myState还是初始空数组。

正确实现方式

把异步逻辑从reducer中剥离,放到组件的useEffect或事件处理函数中,等异步数据获取完成后,再通过dispatch触发状态更新:

1. 调整Reducer,处理数据更新的action

function todoReducer(state, action) {
  switch (action.type) {
    case "LOAD_TODOS_SUCCESS":
      // 用异步获取到的数据更新状态
      return { ...state, todos: action.payload };
    // 其他状态处理逻辑...
    default:
      return state;
  }
}

2. 在组件中执行异步请求并dispatch action

import { useReducer, useEffect } from 'react';

function TodoComponent() {
  // 初始化reducer,初始状态todos为空数组
  const [state, dispatch] = useReducer(todoReducer, { todos: [] });

  useEffect(() => {
    // 封装异步请求逻辑
    async function fetchTodos() {
      try {
        const data = await todoService.getTodo();
        // 数据获取成功后,dispatch更新状态的action
        dispatch({ type: "LOAD_TODOS_SUCCESS", payload: data });
      } catch (err) {
        // 可在这里处理请求失败的情况,比如dispatch LOAD_TODOS_FAILURE
        console.error('获取todo失败:', err);
      }
    }

    fetchTodos();
  }, []); // 空依赖数组确保只在组件挂载时执行一次

  // 后续渲染逻辑...
}

补充说明

  • Reducer的职责是同步更新状态,所有异步操作(比如API请求、定时器)都应该放在reducer外部完成,再通过action传递结果给reducer。
  • 若需要处理加载状态,可以在初始状态中加入isLoading: false,请求开始时dispatchLOAD_TODOS_START设置isLoading: true,请求完成后再更新状态并重置isLoading。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 17:05:28