如何在React中将子元素传递给父元素并完成渲染及报错解决
报错的直接原因
你写的JSX表达式<div></div> 经过编译后生成的是React Element(虚拟DOM描述对象),它只是一个用来记录“要渲染的节点类型、属性、子内容”的普通JS对象,并不是浏览器里真实存在的DOM节点,自然没有原生DOM接口提供的appendChild方法,调用这个方法就会直接抛出类型错误。
你目前的写法完全混淆了原生JS命令式操作DOM的逻辑,和React声明式渲染的核心模型:
- 原生JS逻辑:先拿到真实DOM节点 → 手动创建子节点 → 手动调用appendChild插入到父节点
- React逻辑:构建完整的虚拟元素树 → 交给React渲染器自动把整棵树转成真实DOM,不需要手动操作DOM接口
修正方案
最小改动适配原有逻辑
React原生就支持接收元素数组作为父节点的children属性,你只需要把循环生成的子元素存成数组,直接在构建父div的时候传入即可,完全替代你想手动appendChild实现的效果:
let persons = [{name: 'Bill', age: '25'}, {name: 'John', age: '35'}]; function showPersons() { // 循环生成每一个人员的span元素,组成数组 const personItems = persons.map(person => // 列表项必须加唯一key,用于React的diff渲染优化 <span key={person.name}>Name: {person.name}, age: {person.age}</span> ) // 直接把子元素数组作为div的children传入,不需要appendChild const fatherDiv = <div>{personItems}</div> ReactDOM.render(fatherDiv, document.getElementById('app')) } ReactDOM.render( <button onClick={showPersons}>Show</button>, document.getElementById('app') );
更符合React规范的写法
实际开发中不建议每次交互都重新调用ReactDOM.render,更合理的方式是用状态驱动视图更新:
let persons = [{name: 'Bill', age: '25'}, {name: 'John', age: '35'}]; function App() { // 用状态控制列表的显示隐藏,初始为隐藏 const [isShowPersonList, setIsShowPersonList] = React.useState(false) return ( <div id="app-root"> <button onClick={() => setIsShowPersonList(true)}>Show</button> {/* 条件渲染:状态为true时才展示人员列表 */} {isShowPersonList && ( <div> {persons.map(person => <span key={person.name}>Name: {person.name}, age: {person.age}</span> )} </div> )} </div> ) } ReactDOM.render(<App />, document.getElementById('app'))
这种写法下,视图会完全跟随状态变化自动更新,不需要手动干预DOM渲染流程,也从根源上避免了调用不存在的DOM方法的问题。
顺带提一下你原代码里的小问题:给
showPersons定义的data参数从始至终没有生效,函数入口就直接把传入的data覆盖成了全局的persons数组,如果后续需要传入自定义数据源,可以把覆盖的逻辑删掉,直接使用传入的参数即可。
内容的提问来源于stack exchange,提问作者PinkySweater97
相关产品推荐
相关产品推荐

