Tengo una estructura de árbol como JSON y puede tener n niveles de profundidad. Aquí hay un ejemplo:
"plot": { "population": "All", "gates": [ { "name": "population1", "plot": { "population": "population1", "gates": [ { "name": "population3", "plot": { "population": "population3", } } ] } }, { "name": "population2", "plot": { "population": "population4", } } ] }; Comienza con plot . El es el nivel superior. Una parcela puede tener muchas gates . Estas son esencialmente ramas. Cada gate tiene otra plot , que puede tener varias gates etc.
Quiero generar la plot.population dentro de JSX envuelto en un div . Aquí está mi intento ( MultiStainState es un archivo JSON con el JSON anterior):
function Plot(props) { ... const renderPlots = (plotObject) => { console.log("plotObject is ", plotObject); if (plotObject) { return ( <> <div>{plotObject.population}</div> </> ); } { plotObject.gates.map((gate, gateIndex) => { plotObject(gate.plot); }); } }; return ( <div style={{ height: "200px", }} > Render Plots: {renderPlots(MultiStainState)} </div> ); } Esta salida Render Plots:All y ninguna de las poblaciones de parcelas secundarias.
Presumiblemente, esto se debe a la return dentro de renderPlots() . Siento que necesito usar la recursividad aquí (como he intentado hacer). Pero no puedo entender cómo...
Aquí hay una representación simple de un componente recursivo basado en este artículo . Comprueba si tiene una matriz de puertas de longitud> 0 y, de ser así, representará recursivamente el componente
salvadera
const plot = { "population": "All", "gates": [ { "name": "population1", "plot": { "population": "population1", "gates": [ { "name": "population3", "plot": { "population": "population3", } } ] } }, { "name": "population2", "plot": { "population": "population4", } } ] } const RecursiveComponent = ({ population, gates }) => { const hasGates = gates && gates.length return ( <React.Fragment> <div> {population} </div> {hasGates && gates.map(({name,plot}) => <RecursiveComponent key={name} population={plot.population} gates={plot.gates} />)} </React.Fragment> ); }; const App = props => { return ( <RecursiveComponent population={plot.population} gates={plot.gates} /> //starting point ); }; ReactDOM.render(<App />, document.getElementById("app")); <script crossorigin src="https://unpkg.com/react@16/umd/react.development.js"></script> <script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script> <div id="app"></div>El problema principal con su función renderPlots es que si el plotObject dado no es nulo, la función simplemente devuelve plotObject.population y nunca llega al paso recursivo. Hay algunos otros problemas con esa función, pero voy a ofrecer una reescritura que los abordará.
No estoy seguro del formato de salida deseado exacto, pero voy a usar elementos anidados <div> para que la jerarquía DOM coincida con la estructura JSON.
Querrá devolver un solo objeto JSX con el paso recursivo dentro (la recursión se ve un poco rara en React/JSX en comparación con la programación habitual). También renderPlots la función renderPlots en un componente separado, pero eso es más una elección estilística (lo dejaré para que encuentre un mejor nombre para el componente).
Aquí hay un ejemplo simple:
function PlotRender({ plotObject }) { if (!plotObject) { return null; // just in case } return ( <div> {plotObject.population} {plotObject.gates?.map(e => ( <PlotRender key={e.name} plotObject={e.plot}/> ))} </div> ); }Que se representará como (para los datos de muestra dados):
<div> All <div> population1 <div> population3 </div> </div> <div> population4 </div> </div> Tenga en cuenta también que en el componente <Plot> externo, es probable que deba pasar MultiStainState.plot como accesorio plotObject a <PlotRender> en lugar de solo MultiStainState .