React点击时新增组件是否需要使用state?实现类似insertAdjacentHTML功能
React 动态新增组件实现方案
React 采用声明式的渲染逻辑,和原生手动操作DOM插入内容的思路不同,不需要调用类似insertAdjacentHTML的方法,只需要通过状态控制要渲染的组件列表即可。
现有代码的核心问题
- 事件回调中返回的组件不会被React渲染,只有组件顶层return语句中的内容才会被解析渲染
- 自定义组件名
row必须首字母大写,否则React会将其识别为原生HTML标签 - 当前state仅存储了单个Item实例,无法支持动态新增多个组件的需求
- 存在基础语法错误:ul闭合标签写法错误、FontAwesomeIcon的
icon属性拼写错误
修正后的实现代码
import React, { useState } from 'react' import Item from './Item'; import ChangeableItem from './ChangeableItem'; // 注意提前引入你要新增的ChangeableItem组件 import { library } from '@fortawesome/fontawesome-svg-core'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { faPlusCircle } from '@fortawesome/free-solid-svg-icons'; library.add(faPlusCircle) // 组件名首字母大写 function Row(props) { // 用数组类型的state存储所有要渲染的动态组件配置 const [itemList, setItemList] = useState([]) // 点击加号时新增一条配置 const addItem = () => { // 这里存标识即可,不需要直接存组件实例,后续维护成本更低 setItemList(prev => [...prev, { id: Date.now() }]) } return ( <ul className="global"> {/* 渲染默认的Item组件 */} <Item /> {/* 根据state遍历渲染所有动态新增的ChangeableItem */} {itemList.map(item => ( <ChangeableItem key={item.id} /> ))} <FontAwesomeIcon onClick={addItem} icon={["fas", "plus-circle"]} /> </ul> ) }
补充说明
- 动态渲染的列表元素必须添加唯一的
key属性,避免React做diff更新时出现异常,示例中用时间戳作为唯一值,实际项目建议使用业务唯一ID - 如果后续需要支持删除、修改动态组件的需求,直接操作
itemList数组的对应项即可,React会自动同步视图变化
内容的提问来源于stack exchange,提问作者Richardson
相关产品推荐
相关产品推荐

