Hi everone i have a issue or more over i want to know "How can i create a tree table kind off structure using the nested json". With out using any 3rd part lib/package
I have a nested json like below :
[
{
"id": 1,
"name": "VehicleData",
"owner": "admin",
"sub_details": [
{
"sub_name": "Lexus",
"sub_id": 4,
},
{
"sub_name": "BMW",
"sub_id": 3,
}
]
},
{
"id": 2,
"name": "Mobiles,
"owner": "admin",
"sub_details": [
{
"sub_name": "Apple",
"sub_id": 2,
}
]
},
{
"id": 3,
"name": "Laptop",
"owner": "admin",
"sub_details": []
}
]
What i have tried :-
import React, {useState, useEffect} from 'react';
import classes from './TableData.module.css';
const TableData = () => {
const [oldData, newData] = useState([]);
useEffect(() => {
fetchData();
}, []);
const Id = (dataId) => {
alert(dataId);
};
const Name = (dataName) => {
alert(dataName);
};
const fetchData = async () => {
try {
const response = await fetch('someapi/json');
const data = await response.json();
newData(data);
} catch (e) {
console.warn(e)
}
}
const DisplayData = oldData.map((data) => {
return (
<tr key={
data.id
}>
<td> {
data.id
} </td>
<td> {
data.name
} </td>
<td> {
data.owner
} </td>
<td>
<button onClick={
() => Id(data.id)
}>getId</button>
<button onClick={
() => Name(data.name)
}>getname</button>
</td>
</tr>
)
})
return (
<div>
<div>
<table>
<thead>
<tr>
<th>id</th>
<th>name</th>
<th>owner</th>
</tr>
</thead>
<tbody> {DisplayData} </tbody>
</table>
</div>
</div>
)
}
export default TableData;
what i have done : I have created a table using json and also added button for getting the parent data
what i need and how can i do :
How can i add create the nested structure without using 3rd party plugins and also add button to each row .
How can i get the parent data and child data on each child row button click .
How can i able to toggle & keep open up the nested structure .
if any info url are there it will be great full ?
In React, you must break your data into components. Working with the data as is, in multi-level nesting, is considered bad design - see here for a detailed explanation.
With this in mind, I dedicated one component for each nesting level. This way, the row can manage its sub-row hidden state. Here's the final code - see full demo here - click the "toggle" button:
index.js:
import React, { useState, useEffect } from "react";
import "./styles.css"
const Table = () => {
const [items, setItems] = useState([]);
useEffect(() => {
fetchData();
}, []);
const fetchData = async () => {
try {
const response = await fetch("./data.json");
const data = await response.json();
setItems(data);
} catch (e) {
console.warn(e);
}
};
return <div>
{
items.map((data) => {
return <TableData key={data.id} data={data} />
})
}
</div>;
};
const TableData = (props) => {
const data = props.data;
const [subHidden, setSubHidden] = useState(false);
const Id = (dataId) => {
alert(dataId);
};
const Name = (dataName) => {
alert(dataName);
};
const Toggle = () => {
setSubHidden(state => {
return !state;
});
};
return (
<div >
<span> {data.id} </span>
<span> {data.name} </span>
<span> {data.owner} </span>
<span>
<button onClick={() => Id(data.id)}>getId</button>
<button onClick={() => Name(data.name)}>getname</button>
<button onClick={() => Toggle()}>toggle</button>
</span>
<TableSubDetails
subDetails={data.sub_details}
style={{ display: subHidden ? 'none' : 'block'}}
/>
</div>
);
}
const TableSubDetails = (props) => {
const subDetails = props.subDetails;
return (
<div className="subData" style={props.style}>
{
subDetails.map((subData) => {
return <div key={subData.sub_id}>
<span> {subData.sub_id} </span>
<span> {subData.sub_name} </span>
</div>
})
}
</div>
);
}
export default Table;
styles.css:
.subData {
padding: 5px 15px;
}