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

React状态已更新但JSX不渲染问题排查求助

问题:点击按钮后JSX未更新渲染数据,修改代码保存后却正常显示

尝试展示包含产品及其产品编号的表格,通过console.log查看state发现数据符合预期,但点击“GET Product numbers”按钮时JSX并未更新渲染数据。不过当修改代码并保存后,数据能正常显示在表格中,希望指出问题所在。

import { useState } from "react";

import "./App.css";

function Temp() {
  const [products, setproducts] = useState();
  const [productnumbers, setproductnumbers] = useState([]);
  var final = [];

  const productsArray = products?.split(",").map(function (item) {
    return item.trim();
  });

  async function fetchproducts() {
    productsArray.forEach(async (e, i) => {
      await fetch("API URL", productsArray)
        .then((res) => res.json())
        .then((json) => {
          let q = json.styleId.toString();
          final.splice(i, 0, { key: e, value: q });

          return;
        })
        .catch((ERR) => {
          return ERR;
        });
    });
    setproducts("");
    setproductnumbers(final);
    return;
  }

  var unique = productnumbers.filter(
    (ele, ind) =>
      ind ===
      productnumbers.findIndex(
        (elem) => elem.key === ele.key && elem.value === ele.value
      )
  );
  console.log("new-state", productnumbers);

  return (
    <div>
      <header className="App-header">
        <div className="wrapper">
          <textarea
            value={products}
            onChange={(e) => setproducts(e.target.value)}
            placeholder='Enter products seperated with ","'
            name="skus"
            id="gm-skus"
            cols="30"
            rows="10"
          ></textarea>{" "}
          <button onClick={fetchproducts}>GET Product numbers</button>
        </div>
        <div className="tableContainer">
          <table width="100%">
            <tr>
              <td>Products</td>
              <td>Product numbers</td>
            </tr>
            {unique.map((each, i) => {
              return (
                <tr key={i}>
                  <td>{each.key}</td>
                  <td>{each.value}</td>
                </tr>
              );
            })}
          </table>
        </div>
      </header>
    </div>
  );
}

export default Temp;

问题根源及解决方案

1. 异步循环未等待请求完成

forEach中使用async/await不会等待所有异步请求执行完毕,你在循环结束后立刻调用setproductnumbers(final),此时所有API请求还没返回,final仍是空数组。等请求返回后修改final,但这时候已经执行过状态更新,且final是普通变量,修改它不会触发组件重新渲染。

2. 错误的fetch参数传递

原代码中fetch("API URL", productsArray)的第二个参数不符合fetch API规范,fetch的第二个参数应为请求配置对象(如method、headers、body等),而非要传递的数组数据,需根据API实际要求调整。

修正后的代码

import { useState } from "react";
import "./App.css";

function Temp() {
  const [products, setproducts] = useState();
  const [productnumbers, setproductnumbers] = useState([]);

  const productsArray = products?.split(",").map(item => item.trim());

  async function fetchproducts() {
    if (!productsArray || productsArray.length === 0) return;
    
    // 用Promise.all等待所有异步请求完成
    const requests = productsArray.map(async (product) => {
      try {
        // 根据实际API需求调整fetch参数
        const res = await fetch("API URL", {
          method: "POST", // 假设是POST请求
          headers: { "Content-Type": "application/json" },
          body: JSON.stringify({ product })
        });
        const json = await res.json();
        return { key: product, value: json.styleId.toString() };
      } catch (err) {
        console.error(`获取${product}编号失败:`, err);
        return { key: product, value: "获取失败" };
      }
    });

    const finalData = await Promise.all(requests);
    setproducts("");
    setproductnumbers(finalData);
  }

  const unique = productnumbers.filter(
    (ele, ind) =>
      ind ===
      productnumbers.findIndex(
        (elem) => elem.key === ele.key && elem.value === ele.value
      )
  );

  console.log("new-state", productnumbers);

  return (
    <div>
      <header className="App-header">
        <div className="wrapper">
          <textarea
            value={products}
            onChange={(e) => setproducts(e.target.value)}
            placeholder='Enter products seperated with ","'
            name="skus"
            id="gm-skus"
            cols="30"
            rows="10"
          ></textarea>{" "}
          <button onClick={fetchproducts}>GET Product numbers</button>
        </div>
        <div className="tableContainer">
          <table width="100%">
            <tr>
              <td>Products</td>
              <td>Product numbers</td>
            </tr>
            {unique.map((each, i) => (
              <tr key={i}>
                <td>{each.key}</td>
                <td>{each.value}</td>
              </tr>
            ))}
          </table>
        </div>
      </header>
    </div>
  );
}

export default Temp;

关键优化点

  • 使用Promise.all统一等待所有API请求完成,确保获取到完整数据后再更新状态
  • 修正fetch的参数传递,符合API调用规范
  • 移除组件内的普通变量final,直接通过异步请求结果生成新数组,保证状态更新时传递新的数组引用,触发React重新渲染

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.29 01:52:40