I'm creating a react SPA, my problem is that when I go to the page where my table is only the TableRow information that is rendered, I've tried using conditional rendering but I still have the same problem.
this is the page with the table component(sumariosDenseTable):
import React, { useState, useEffect } from 'react';
import { Container } from './styles';
import SumariosDenseTable from '../../components/SumariosDenseTable';
export default function Sumarios() {
return (
<Container>
<div className="title">Listar Sumários</div>
<SumariosDenseTable />
</Container>
);
}
when I'm redirected to this page only TableHead information is rendered.
this is the table component code:
function createData(conteudo, disciplina, curso, dataAula) {
return { conteudo, disciplina, curso, dataAula };
}
const rows = [];
export default function SumariosDenseTable() {
const { sumarios } = useListarSumarios();
const { cursoSigla } = useListarAulas();
React.useEffect(() => {
if (rows.length !== sumarios.length) {
sumarios.map((sum) =>
rows.push(
createData(
sum.sumario.conteudo,
sum.disciplina.codigo,
cursoSigla(sum.cursos),
sum.data
)
)
);
}
}, [sumarios, rows]);
return (
<TableContainer component={Paper}>
<Table sx={{ minWidth: 650 }} size="small" aria-label="a dense table">
<TableHead>
<TableRow>
<TableCell>Conteudo</TableCell>
<TableCell align="right">Disciplina</TableCell>
<TableCell align="right">Cursos</TableCell>
<TableCell align="right">Data</TableCell>
</TableRow>
</TableHead>
<TableBody>
{rows.map((row) => (
<TableRow
key={row.conteudo}
sx={{ '&:last-child td, &:last-child th': { border: 0 } }}
>
<TableCell component="th" scope="row">
{row.conteudo}
</TableCell>
<TableCell align="right">{row.disciplina}</TableCell>
<TableCell align="right">{row.curso}</TableCell>
<TableCell align="right">{row.dataAula}</TableCell>
</TableRow>
))}
</TableBody>
</Table>
</TableContainer>
);
}
the problem is that the table component is rendered before the rows array is completely filled how do I get the table to be rendered only when the row array is completely filled ???
You need to use useState
(state hook) for the rows
variable. This way, when the useEffect
is done populating the rows
variable, the component will be re-rendered.
You can learn more about the state hook here.
The code should look like this (explanation added as comments):
// Add useState import at the top
import { useState } from "react";
// All other imports and the rest of the top half of your code are still here
export default function SumariosDenseTable() {
const { sumarios } = useListarSumarios();
const { cursoSigla } = useListarAulas();
// Use useState for the rows and set it's initial value to empty ([])
const { rows, setRows } = useState([]);
React.useEffect(() => {
if (rows.length !== sumarios.length) {
const tempRows = [];
sumarios.map((sum) =>
tempRows.push(
createData(
sum.sumario.conteudo,
sum.disciplina.codigo,
cursoSigla(sum.cursos),
sum.data
)
)
);
// update the rows variable via the hook
setRows(tempRows);
}
}, [sumarios, rows]);
if (rows.length > 0) {
return (
<TableContainer component={Paper}>
//The rest of the table code here
</TableContainer>
);
} else {
// If no rows, don't render anything at all
return null;
}
}