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

并发请求多服务器创建组件,useState更新列表异常求排查

问题分析与修正

你的代码存在三个核心问题:

1. useState更新语法错误

setdropdownItems 的参数必须是一个完整数组,你当前只展开了原有数组但未包裹到新数组中,正确的写法应该是用 [...prevItems, newItem] 这种数组形式传递给状态更新函数。

2. 异步请求的闭包陷阱

forEach 里的 fetch 是异步操作,当回调执行时,dropdownItems 捕获的是组件初始渲染时的空数组状态,导致每次更新都是基于空数组添加元素,最终只会保留最后一个请求成功的组件。解决这个问题要使用函数式更新,让状态更新依赖上一次的最新状态。

3. 直接存储JSX到state的不合理性

React状态更适合存储原始数据(比如服务器信息),而非直接存储组件。直接存JSX会让状态难以维护,也不符合React的设计模式,应该先存储数据,再在渲染阶段动态生成组件。


修正后的代码示例

import { useState, useEffect } from 'react';

const YourComponent = ({ session }) => {
  const [reachableServers, setReachableServers] = useState([]);

  useEffect(() => {
    const checkServers = async () => {
      // 用map配合Promise.all批量处理异步请求,便于控制流程
      const serverCheckPromises = session.reachablePartner.map(async (serverPartner) => {
        try {
          const res = await fetch(`http://${serverPartner.ipAddress}/api/isonline`);
          // 根据接口实际返回判断服务器是否可达,这里假设res.ok代表成功
          if (res.ok) {
            return serverPartner;
          }
        } catch (err) {
          console.log(`${serverPartner.serverName} 无法连接`);
        }
        return null;
      });

      // 等待所有请求完成,过滤掉不可达的服务器
      const checkResults = await Promise.all(serverCheckPromises);
      const validServers = checkResults.filter(server => server !== null);
      setReachableServers(validServers);
    };

    checkServers();
  }, [session.reachablePartner]);

  // 渲染阶段根据数据生成组件
  return (
    <div>
      {reachableServers.map(server => (
        <DropDownItem
          key={server.ipAddress}
          onClick={() => {
            window.location.replace(`http://${server.ipAddress}/`);
          }}
        >
          {server.serverName}
        </DropDownItem>
      ))}
    </div>
  );
};

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.16 13:54:57