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

React Hooks调用API后如何实现多条数据立即同步显示

问题根因

  • 状态更新未返回新引用:直接修改原有数组的内部属性后返回原数组,React浅比较检测不到状态变化,不会触发重渲染,是点击第二次才显示的核心原因。
  • 异步逻辑未统一收口:单独监听每个请求返回更新状态,就算渲染正常也会出现逐行显示的情况,无法实现两行同时出现。
  • 代码存在遗漏定义:useDataApi 中未定义 setID 方法,且初始状态的用户对象缺少steamId字段,会导致请求参数异常。
  • 闭包捕获旧状态:在自定义Hook顶层定义stateCopy,异步方法中捕获的永远是初始化时的旧数组,导致状态更新逻辑异常。

修复方案

核心改动逻辑:

  1. 去掉闭包中的stateCopy,所有状态更新都生成全新的数组对象,保证React能检测到状态变化
  2. 用Promise.all等待所有异步请求完成后,统一生成新状态一次更新,实现两行数据同时渲染
  3. 补全缺失的setID方法和初始字段

修复后代码

index.js(无改动)

import React from "react";
import ReactDOM from "react-dom";
import App from "./test";

ReactDOM.render(<App />, document.getElementById("root"));

app.js

import React, { useState } from "react";

const useDataApi = (initialState) => {
  const [state, setState] = useState(initialState);

  // 补全修改steamId的方法
  const setID = (number, value) => {
    setState(prev => {
      const newState = [...prev];
      newState[number] = {...newState[number], steamId: value};
      return newState;
    })
  }

  const getFetch = async (id) => {
    if (!id) return {Date: ''};
    const requestID = await fetch(`https://api.covid19api.com/summary`);
    return await requestID.json();
  };

  const setInfo = async () => {
    // 等待所有请求完成
    const resultList = await Promise.all(
      state.map(item => getFetch(item.steamId))
    )
    // 生成全新的状态数组
    const newState = state.map((item, index) => {
      return {...item, date: resultList[index].Date || ''}
    })
    // 统一更新状态
    setState(newState)
  };

  return { state, setInfo, setID };
};

const Children = ({ data }) => {
  return (
    <ul>
      {data.map((item) => (
        <li key={item.id}>
          {item.date ? item.date : "Not data"}
          <br/>
        </li>
      ))}
    </ul>
  );
};

const InfoUsers = ({ number, steamid, change }) => {
  return (
    <input
      value={steamid || ''}
      numb={number}
      onChange={(e) => change(number, e.target.value)}
    />
  );
};

function App() {
  // 初始状态补全steamId字段
  const usersProfiles = [
    { date: "", id: 1, steamId: "" },
    { date: "", id: 2, steamId: "" }
  ];
  const profiles = useDataApi(usersProfiles);

  return (
    <div>
      <InfoUsers number={0} steamid={profiles.state[0].steamId} change={profiles.setID} />
      <InfoUsers number={1} steamid={profiles.state[1].steamId} change={profiles.setID} />
      <button onClick={() => profiles.setInfo()}>Get</button>
      <Children data={profiles.state} />
    </div>
  );
}

export default App;

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.11 14:39:01