React中点击按钮添加组件的实现方法及报错解决
问题原因及解决方法
错误原因
你直接把JSX元素<Cargo />传给原生DOM的insertBefore方法,这是行不通的——JSX只是React的语法糖,编译后返回的是React元素对象,不是浏览器能识别的原生DOM Node,所以会触发类型错误。
推荐实现方式(React原生状态管理)
React的核心是通过状态驱动UI,不要直接操作原生DOM,正确的做法是用状态管理组件的渲染列表:
方式1:维护组件数组,插入到指定位置
import { useState } from 'react'; function YourComponent() { // 初始化容器内的元素列表,包含原有内容 const [containerElements, setContainerElements] = useState([ <div key="elem1">原有元素1</div>, <div key="elem2">原有元素2</div>, <div key="elem3">原有元素3</div> ]); const addCargo = () => { // 复制原数组,避免直接修改状态 const newElements = [...containerElements]; // 在索引2的位置插入新的Cargo组件(对应原第三个子元素之前) newElements.splice(2, 0, <Cargo key={`cargo-${Date.now()}`} />); setContainerElements(newElements); }; return ( <div> <button onClick={addCargo}>添加Cargo</button> <div id="addCargoContainer"> {containerElements} </div> </div> ); }
方式2:用计数控制渲染数量(适合不需要指定插入位置的场景)
import { useState } from 'react'; function YourComponent() { const [cargoNum, setCargoNum] = useState(0); const addCargo = () => { setCargoNum(prev => prev + 1); }; return ( <div> <button onClick={addCargo}>添加Cargo</button> <div id="addCargoContainer"> {/* 原有元素 */} <div>原有元素1</div> <div>原有元素2</div> {/* 动态渲染Cargo组件 */} {Array.from({ length: cargoNum }).map((_, idx) => ( <Cargo key={`cargo-${idx}`} /> ))} <div>原有元素3</div> </div> </div> ); }
注意:动态生成的组件必须加唯一的key,避免React渲染时出现性能问题或错误。
不推荐的原生DOM操作方式(仅作参考)
如果非要用原生DOM插入,需要先把React组件渲染成真实DOM节点再插入,但这种方式会脱离React的状态管理,后续维护容易出问题:
import ReactDOM from 'react-dom/client'; const addCargo = () => { const parentElement = document.getElementById("addCargoContainer"); // 创建临时容器 const tempDiv = document.createElement('div'); // 把Cargo组件渲染到临时容器 const root = ReactDOM.createRoot(tempDiv); root.render(<Cargo />); // 插入渲染后的真实DOM节点 parentElement.insertBefore(tempDiv.firstChild, parentElement.children[2]); };
内容的提问来源于stack exchange,提问作者Bot Ellis
相关产品推荐
相关产品推荐

