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
相关产品推荐
相关产品推荐

