Tengo el siguiente código:
<TreeView aria-label="controlled" defaultCollapseIcon={<ExpandMoreIcon />} defaultExpandIcon={<ChevronLeftIcon />} expanded={expanded} selected={selected} onNodeToggle={handleToggle} onNodeSelect={handleSelect} multiSelect > { rows.data.map((item: IPTreeModel)=> { return ( <TreeItem nodeId={item.id} label={item.subnet} onClick={item.has_child ? (e: MouseEvent)=> loadChildren(e, item.subnet) : ()=> ''}> {/*here*/} </TreeItem> ) }) } </TreeView>Y debajo está mi función:
const loadChildren = (e: MouseEvent, id: number | string) => { // fetch new data based on the ID parameter, and append the output as a TreeItem element. } Ahora necesito agregar un nuevo elemento <TreeItem> al último <TreeItem> en caso de que el usuario haga clic en la función loadChildren .
¿Cómo es la forma de reaccionar de hacer esto?
Agregue un nuevo campo a su objeto rows.data y asegúrese de almacenarlo como un estado. haga esto clonando su matriz anterior, haciendo un retroceso y luego configurando un nuevo estado con su nueva matriz modificada. Esto activará el redibujado del componente TreeView .
Edición 1:
Aquí hay un ejemplo rápido de cómo podrías hacer esto. Haga que onClick llame a la función addData para agregar datos a su estructura.
const [data, setData] = useState([]); const addData = () => { const tmp = data.slice(); tmp.push([new data]); setData(tmp); } return ( <div className="App"> <TreeView> {data.map((item) => { <TreeItem data={item} ></TreeItem> })} </TreeView> </div> );Terminé resolviendo el problema de la siguiente manera:
const loadChildren = (e: any, id: number | string) => { setLoadingChildren(true) getIpState(id).then(res=> { setRows({ ...rows, data: rows.data.map((item: any) => item.id == id ? {...item, child: res.data} : item) }) setLoadingChildren(false) }).catch(err => { console.log(err) setLoadingChildren(false) }) } const traverse = (o: any) => { if (!loadingChildren){ return o.map((item: any, key: number) => { let extra = item.hasOwnProperty('extra') ? item.extra : item return ( <TreeItem key={key} nodeId={extra.id} icon={item.has_child ? <ChevronLeftIcon /> : ''} label={item.subnet} onClick={extra.has_child ? (e)=> loadChildren(e, extra.id) : ()=> ''}> {item.child ? traverse(item.child) : ''} </TreeItem> ) } ) } }Y mostrar la salida como:
<TreeView aria-label="controlled" defaultCollapseIcon={<ExpandMoreIcon />} defaultExpandIcon={<ChevronLeftIcon />} expanded={expanded} selected={selected} onNodeToggle={handleToggle} onNodeSelect={handleSelect} multiSelect > {traverse(rows.data)} </TreeView>