React动态新增子组件及动态创建State的实现方案问询
动态新增React子组件的解决方案
问题背景
项目包含App.jsx和Child.jsx两个组件,当前手动渲染3个子组件,数据由父组件传递。需求是添加按钮实现点击后在第三个子组件后动态新增子组件,核心问题如下:
Q1:父组件维护数据以避免显示状态切换丢失数据,如何动态创建额外的State?
Q2:点击新增按钮后,如何在第三个子组件之后创建新的组件?
解决方案
Q1:用数组State统一管理子组件数据
不要为每个子组件单独声明childNdata和showChildN这类独立State,而是用数组State统一存储所有子组件的状态信息(包括唯一标识、展示数据、显示状态)。新增子组件时,只需向数组中添加新对象即可,无需手动创建新的独立State,完美适配动态扩展需求。
Q2:通过数组追加实现组件后置新增
点击新增按钮时,向数组State的末尾添加新的子组件配置对象,渲染时遍历数组生成子组件,新组件自然会出现在现有组件的最后(即第三个子组件之后)。
修改后的代码示例
App.jsx
import React, { useState, useEffect } from 'react'; import { Child } from './Child.jsx'; export function App(props) { // 数组统一管理所有子组件状态:id(唯一标识)、data(展示数据)、show(显示状态) const [childrenList, setChildrenList] = useState([ { id: 1, data: 'child1', show: true }, { id: 2, data: 'child2', show: true }, { id: 3, data: 'child3', show: true } ]); useEffect(() => { console.log('parent was rendered'); }); // 新增子组件逻辑 const addChild = () => { const newId = childrenList.length + 1; setChildrenList(prevList => [ ...prevList, { id: newId, data: `child${newId}`, show: true } ]); }; // 更新指定子组件的数据 const updateChildData = (id, newData) => { setChildrenList(prevList => prevList.map(child => child.id === id ? { ...child, data: newData } : child ) ); }; // 切换指定子组件的显示状态 const toggleChildShow = (id) => { setChildrenList(prevList => prevList.map(child => child.id === id ? { ...child, show: !child.show } : child ) ); }; return ( <div className='App'> <button onClick={addChild}>add child</button> <br/><br/> {/* 遍历数组渲染所有子组件及控制按钮 */} {childrenList.map(child => ( <div key={child.id}> <button onClick={() => toggleChildShow(child.id)}> Show {child.data} </button> {child.show && ( <Child data={child.data} setData={(newData) => updateChildData(child.id, newData)} /> )} <br/><br/> </div> ))} </div> ); } console.log('Hello console');
Child.jsx
import React, { useEffect } from 'react'; export const Child = (props) => { const { data, setData } = props; useEffect(() => { console.log(data); }); return ( <> <h1>This is {data}</h1> <input value={data} onChange={(e) => setData(e.target.value)} /> </> ); };
内容的提问来源于stack exchange,提问作者Ae Leung
相关产品推荐
相关产品推荐

