I have seen some examples of creating react tables using API data before but no one used the header(key) from API data to set headers in react table. Please someone help me to do this.
In my code, I have extracted headers from API data in an array. Then I need to pass that values in columns as Headers and accessor values. But I don't understand how to do that.
Here's the API = https://reqres.in/api/users?page=1
I am fetching data from this Axios API in a hook :
import axios from 'axios';
let userRole;
const [userData, setUserData] = useState({});
useEffect(()=>{
axios.get(`https://reqres.in/api/users?page=1`)
.then(res => {
userRole = res.data.data;
console.log("Data from API",userRole);
userRole.sort((a,b) => a.first_name.localeCompare(b.first_name) )
setUserData(userRole);
});
}, []);
//console.log(userData);
API Data from UserRole looks like this : enter image description here
let headerList = [];
function BasicTableComponent() {
//console.log("Full data in array",userData)
// EXTRACT VALUE FOR HTML HEADER.
for (var i = 0; i < userData.length; i ) {
for (var key in userData[i]) {
if (headerList.indexOf(key) === -1) {
headerList.push(key);
}
}
}
console.log("Column Header List check",headerList);
/*Now instead of this hardcoded method I want to pass values
from my headerList for Header and accessor in my columns.*/
const columns = React.useMemo(
() => [
{
Header: 'Column 1',
accessor: 'col1', // accessor is the "key" in the data
},
{
Header: 'Column 2',
accessor: 'col2',
},
],
[]
)
//console.log("Column Header",columns)
const {
getTableProps,
getTableBodyProps,
headerGroups,
rows,
prepareRow,
} = useTable({ columns, userData })
return (
<table {...getTableProps()} style={{ border: 'solid 1px blue' }}>
<thead>
{headerGroups.map(headerGroup => (
<tr {...headerGroup.getHeaderGroupProps()}>
{headerGroup.headers.map(column => (
<th
{...column.getHeaderProps()}
style={{
borderBottom: 'solid 3px red',
background: 'aliceblue',
color: 'black',
fontWeight: 'bold',
}}
>
{column.render('Header')}
</th>
))}
</tr>
))}
</thead>
<tbody {...getTableBodyProps()}>
{rows.map(row => {
prepareRow(row)
return (
<tr {...row.getRowProps()}>
{row.cells.map(cell => {
return (
<td
{...cell.getCellProps()}
style={{
padding: '10px',
border: 'solid 1px gray',
background: 'papayawhip',
}}
>
{cell.render('Cell')}
</td>
)
})}
</tr>
)
})}
</tbody>
</table>
)
}
CodePudding user response:
As per my understanding, you are looking to create an array of objects that has two properties. One is 'column name' that is going to be used as header in the table and the second is 'key' that is used to access the value from 'userData'.
I have modified useEffect to retrieve data, set userData and set columns.
Since you want columns to hold dynamic data, I have placed that part inside useEffect because it is dependent on the data that we retrieve from API. Sorry for not formatting code properly.
const ParentComponent = (props) => { const [userData, setUserData] = useState({}); const [loading, setLoading] = useState(false); const [columns, setColumns] = useState([]); const getData = async () => { await axios.get("https://reqres.in/api/users?page=1").then((resp) => { let data = resp.data.data.sort((a, b) => a.first_name.localeCompare(b.first_name) ); let cols = Object.keys(data[0]).map((key) => { return { Header: key.toUpperCase(), accessor: key }; }); setUserData(data); setColumns(cols); setLoading(false); } useEffect(() => { setLoading(true); getData(); }, []); return( <TableComponent columns={columns} userData={userData} /> )}