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

React中使用state实现点击添加Item功能失效如何解决?

问题解决说明

核心错误原因

  • 你调用add.items.push(<Item/>)时,push方法返回的是数组更新后的长度值,而非更新后的数组本身,你直接将这个数字传给setAdd,就把原本存储数组对象的状态覆盖成了数字,后续读取add.items自然会报错,出现异常渲染结果。
  • 直接修改原状态数组属于可变更新,违反React状态更新的不可变原则,会导致组件无法正确触发重渲染。
  • 组件名itmes首字母小写不符合React组件命名规范,会被识别为普通HTML标签而非自定义组件。
  • 额外优化点:不建议直接把组件实例存储在状态中,更合理的做法是存储数据标识,渲染时通过遍历生成对应组件,降低状态耦合度。

修正后的可运行代码

import React, { useState } from 'react'
import Item from './Item';
// 组件名首字母大写,符合React规范
function Items(props) {
  // 单独将items数组作为状态,不需要嵌套多余对象
  const [items, setItems] = useState([<Item key={1} />]);
  return (
    <ul>
      {items}
      {/* 用展开运算符生成新数组,符合不可变更新原则,补充箭头函数语法缺失的=>符号 */}
      <FontAwesomeIcon 
        className="changable margin-left" 
        onClick={() => {
          setItems(prev => [...prev, <Item key={prev.length + 1} />])
        }} 
        icon={["fas", "plus-circle"]}
      />
    </ul>
  )
}

更推荐的实现方式(不存储组件实例到状态)

import React, { useState } from 'react'
import Item from './Item';

function Items(props) {
  // 状态仅存储条目数量,后续要给条目传自定义数据也更方便
  const [itemCount, setItemCount] = useState(1);
  return (
    <ul>
      {/* 遍历生成Item组件,统一管理渲染逻辑 */}
      {Array.from({length: itemCount}).map((_, index) => <Item key={index} />)}
      <FontAwesomeIcon 
        className="changable margin-left" 
        onClick={() => setItemCount(prev => prev + 1)} 
        icon={["fas", "plus-circle"]}
      />
    </ul>
  )
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.07 11:48:03