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

React中如何将空数组countData转为useState状态实现DOM更新

问题根源

你修改后的代码存在3个核心错误导致DOM不更新:

  • useState用法错误:useState返回值是长度为2的数组,第一个元素是状态值,第二个是触发更新的状态修改函数,你直接将返回值赋值给countData,后续调用push操作完全不符合状态更新规范
  • 状态初始值错误:countData本应是数组类型的表格行数据,你传入的初始值是数字0,类型完全不匹配
  • 普通变量修改不会触发重渲染:theWordCount是组件内的普通临时变量,即使你修改了它的值,React也不会感知到,自然不会触发DOM更新

正确实现步骤

  1. 正确声明数组类型的状态,初始值为空数组
  2. 把生成表格行的逻辑和状态更新绑定,每次计算完新的行数据后,通过状态修改函数提交更新,触发重渲染
  3. 排序操作完成后,重新生成行数据并更新状态

完整可运行代码

import "./styles.css";
import text from "./text.js";
import React, { useState } from "react";

export default function App() {
  const allTheWords = text.split(" ");
  // 正确声明countData状态,初始值为空数组
  const [countData, setCountData] = useState([]);

  // 封装生成表格行并更新状态的逻辑
  const createTable = (wordCountObj) => {
    const newCountData = [];
    for (const property in wordCountObj) {
      newCountData.push(
        <tr key={property}>
          <td>{property}</td>
          <td>{wordCountObj[property]}</td>
        </tr>
      );
    }
    // 调用set函数更新状态,触发重渲染
    setCountData(newCountData);
  };

  // 初始加载时生成未排序的词频统计
  React.useEffect(() => {
    const theWordCount = {};
    for (const num of allTheWords) {
      theWordCount[num] = theWordCount[num] ? theWordCount[num] + 1 : 1;
    }
    createTable(theWordCount);
  }, []);

  const sortWords = () => {
    const theWordCount = {};
    // 先统计词频
    for (const num of allTheWords) {
      theWordCount[num] = theWordCount[num] ? theWordCount[num] + 1 : 1;
    }
    // 排序词频对象
    const sortedWordCount = Object.entries(theWordCount)
      .sort(([, a], [, b]) => a - b)
      .reduce((r, [k, v]) => ({ ...r, [k]: v }), {});
    // 生成排序后的表格行,更新状态
    createTable(sortedWordCount);
  };

  return (
    <div>
      <button onClick={sortWords}>SORT WORDS</button>
      <table>
        <tbody>
          <tr>
            <th>Word</th>
            <th>Count</th>
          </tr>
          {countData}
        </tbody>
      </table>
    </div>
  );
}

额外优化建议

你也可以不用把JSX元素存在状态里,只把词频统计对象存在状态中,渲染的时候直接遍历状态生成表格行,代码可维护性更高:

// 声明词频状态
const [wordCount, setWordCount] = useState({});
// 渲染时直接遍历
{Object.entries(wordCount).map(([word, count]) => (
  <tr key={word}>
    <td>{word}</td>
    <td>{count}</td>
  </tr>
))}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.30 11:06:05