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

React TypeScript多API调用及状态追加问题求助

React + TypeScript setState 问题与优化方案

1. 解决 useEffect 开发模式触发两次的问题

React 18 的 StrictMode 会在开发环境下重复执行挂载阶段的副作用(包括 useEffect),目的是提前检测潜在的逻辑漏洞。除了你已做的去重处理,还可以优化成更可靠的方案:

  • 给获取地点数据的 useEffect 加上明确的空依赖数组 [],确保组件挂载时仅执行一次请求;
  • 用地点的唯一标识(比如 id)做去重,避免依赖内容去重的不确定性:
    // 假设原始地点数据有唯一id字段
    const uniqueLocations = Array.from(
      new Map(rawLocations.map(item => [item.id, item])).values()
    );
    

2. 修复 reservationData 无法追加的问题

不要用 any[] 模糊类型定义,建议先明确预订数据的类型,同时用函数式更新确保状态更新的可靠性:

// 定义预订数据的具体类型
interface Reservation {
  id: string;
  locationId: string;
  date: string;
  // 根据实际API返回补充字段
}

const [reservationData, setReservationData] = useState<Reservation[]>([]);

// 获取新预订数据后,用函数式更新追加
setReservationData(prevData => [...prevData, ...newReservations]);

函数式更新能确保每次都是基于最新的状态值进行修改,避免 setState 异步特性导致的状态覆盖问题。

3. 代码重构与组件拆分建议

(1)抽离自定义 Hook 封装数据逻辑

把 API 请求和数据处理逻辑拆成独立的自定义 Hook,让组件只负责 UI 渲染:

// hooks/useLocations.ts
import { useState, useEffect } from 'react';
import api from '../api';

interface LocationOption {
  label: string;
  value: string;
}

export const useLocations = () => {
  const [locations, setLocations] = useState<LocationOption[]>([]);
  const [loading, setLoading] = useState(false);

  useEffect(() => {
    const fetchLocations = async () => {
      setLoading(true);
      try {
        const res = await api.get('/locations');
        // 直接在Hook里完成MultiSelect的格式转换
        const formattedOptions = res.data.map(item => ({
          label: item.name,
          value: item.id
        }));
        setLocations(formattedOptions);
      } catch (err) {
        // 这里可以添加错误提示,比如用Mantine的Notification组件
        console.error('获取地点数据失败:', err);
      } finally {
        setLoading(false);
      }
    };
    fetchLocations();
  }, []);

  return { locations, loading };
};

同理可以封装 useReservations Hook,负责根据选中地点获取预订数据。

(2)拆分独立UI组件

把页面拆成专注单一职责的小组件:

  • LocationSelector:封装 Mantine MultiSelect 的配置,接收地点列表、选中值、 onChange 回调;
  • ReservationList:接收预订数据数组,负责渲染列表项和空状态;
    主组件只需要串联这两个组件,处理选中地点后的逻辑触发。

(3)状态管理进阶优化

如果后续业务逻辑变复杂,建议用 React Query 替代手动 setState 管理 API 数据:它自带加载/错误状态、数据缓存、自动刷新等能力,能大幅减少重复的状态管理代码。

(4)完善错误处理

给所有 API 请求添加错误捕获和用户提示,比如用 Mantine 的 showNotification 展示错误信息,避免静默失败影响用户体验。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 14:02:47