Estoy escribiendo un código en reaccionar, donde quiero mostrar los datos json en la tabla HTML. Quiero que esto sea dinámico. es decir, independientemente del tipo de datos json que esté usando, debería mostrarse en formato tabular.
Aquí está mi código con datos de muestra.
const jsArray = [{"Model":"Mazda RX4","mpg":21,"cyl":6},{"Model":"Mazda RX4 Wag","mpg":21,"cyl":6},{"Model":"Datsun 710","mpg":22.8,"cyl":""},{"Model":"Hornet 4 Drive","mpg":21.4,"cyl":""},{"Model":"Hornet Sportabout","mpg":18.7,"cyl":8},{"Model":"Valiant","mpg":18.1,"cyl":6}]; {jsArray.length > 0 && ( <table> <thead> {jsArray.map((item, idx) => idx === 0 ? ( <th key={idx}> {Object.values(item).forEach((val) => ( <td>{val}</td> ))} </th> ) : ( <tr key={idx}> {Object.values(item).forEach((val) => ( <td>{val}</td> ))} </tr> ) )} </thead> </table> )}
Cuando ejecuto este código, no se procesa nada. Cuando reemplazo <tr key={idx}>{Object.values(item).forEach((val)=> (<td>{val}</td>))}</tr>
con null
, en mi salida Veo nulo impreso en mi front-end. Por favor, hágame saber dónde me estoy equivocando.
Puedes hacerlo así:
const data = JSON.parse(jsArray); const keys = Object.keys(data.length ? data[0] : {}); return ( <div className="App"> {jsArray.length > 0 && ( <table> <thead> <tr> {keys.map((item, idx) => ( <th key={idx}>{item}</th> ))} </tr> </thead> <tbody> {data.map((item, idx) => ( <tr key={idx}> {keys.map((key, idx) => ( <td>{item[key]}</td> ))} </tr> ))} </tbody> </table> )} </div> );
Podría hacerlo más fácil si dividiera toda esa lógica en funciones más útiles.
getHeadings
maps
el primer objeto y toma sus keys
.
getRows
maps
todos los datos y llama a getCells
con los datos de cada objeto.
getCells
maps
el objeto y usa Object.values
para obtener la información de cada celda.
De esta manera su componente es mucho más limpio.
// `map` over the first object in the array // and get an array of keys and add them // to TH elements function getHeadings(data) { return Object.keys(data[0]).map(key => { return <th>{key}</th>; }); } // `map` over the data to return // row data, passing in each mapped object // to `getCells` function getRows(data) { return data.map(obj => { return <tr>{getCells(obj)}</tr>; }); } // Return an array of cell data using the // values of each object function getCells(obj) { return Object.values(obj).map(value => { return <td>{value}</td>; }); } // Simple component that gets the // headers and then the rows function Example({ data }) { return ( <table> <thead>{getHeadings(data)}</thead> <tbody>{getRows(data)}</tbody> </table> ); } const data = [{"Model":"Mazda RX4","mpg":21,"cyl":6},{"Model":"Mazda RX4 Wag","mpg":21,"cyl":6},{"Model":"Datsun 710","mpg":22.8,"cyl":""},{"Model":"Hornet 4 Drive","mpg":21.4,"cyl":""},{"Model":"Hornet Sportabout","mpg":18.7,"cyl":8},{"Model":"Valiant","mpg":18.1,"cyl":6}]; ReactDOM.render( <Example data={data} />, document.getElementById('react') );
table { border: 1px solid #dfdfdf; border-collapse: collapse; } th { background-color: #efefef; text-align: left; text-transform: uppercase; } td { border: 1px solid #efefef; } td, th { padding: 0.4em; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.2/umd/react.production.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.2/umd/react-dom.production.min.js"></script> <div id="react"></div>