简体   繁体   中英

ReactJS table with material ui

I am trying to use the material UI minimized table to create a dashboard https://material-ui.com/pt/components/tables/

I ran into an issue that I'm stuck with for the last 5 hours. I could successfully render the data from my database to display in the table. However, when I retrieve the data using the map function, all is displayed in one single row x5.

Picture: Front-end view

I'm trying to display the name and data in different rows and not "Sue Flavio John Doe rajid" because each is a different object.

I'd appreciate some help to understand where is my logical mistake.

function EmployeeList() {
  const [employeeList, setEmployeeList] = useState([]);

  console.log(employeeList);

  useEffect(() => {
    Axios.get("http://localhost:4000/vacations_cs_read").then((response) => {
      setEmployeeList(response.data);
    });
  }, []);

  const Row = () => {
    const [open, setOpen] = React.useState(false);
    const classes = useRowStyles();

    return (
      <React.Fragment>
        <TableRow className={classes.root}>
          <TableCell>
            <IconButton
              aria-label="expand row"
              size="small"
              onClick={() => setOpen(!open)}
            >
              {open ? <KeyboardArrowUpIcon /> : <KeyboardArrowDownIcon />}
            </IconButton>
          </TableCell>
          <TableCell component="th" scope="row">
            {employeeList.map((val, key) => {
              return <td>{val.employeeName}</td>;
            })}
          </TableCell>
          <TableCell align="left">
            {employeeList.map((val, key) => {
              const day = new Date(val.employeeStartDay).toLocaleDateString(
                "pt-BR"
              );
              return <td>{day}</td>;
            })}
          </TableCell>
          <TableCell align="left">
            <p>-</p>
          </TableCell>
          <TableCell align="left">
            <p>-</p>
          </TableCell>
          <TableCell align="left">
            <p>-</p>
          </TableCell>
        </TableRow>
        <TableRow>
          <TableCell style={{ paddingBottom: 0, paddingTop: 0 }} colSpan={6}>
            <Collapse in={open} timeout="auto" unmountOnExit>
              <Box margin={1}>
                <Typography variant="h6" gutterBottom component="div">
                  History
                </Typography>
                <Table size="small" aria-label="purchases">
                  <TableHead>
                    <TableRow>
                      <TableCell>From</TableCell>
                      <TableCell>To</TableCell>
                      <TableCell align="left">Days</TableCell>
                      <TableCell align="left">Paid</TableCell>
                    </TableRow>
                  </TableHead>
                  <TableBody>
                    {/* {row.history.map(() => (
                      <TableRow>
                        <TableCell component="th" scope="row"></TableCell>
                        <TableCell></TableCell>
                        <TableCell align="left"></TableCell>
                        <TableCell align="left"></TableCell>
                      </TableRow>
                    ))} */}
                  </TableBody>
                </Table>
              </Box>
            </Collapse>
          </TableCell>
        </TableRow>
      </React.Fragment>
    );
  };

  Row.propTypes = {
    row: PropTypes.shape({
      name: PropTypes.string,
      startDate: PropTypes.string,
      shift: PropTypes.string,
      daysReceived: PropTypes.number,
      daysUsed: PropTypes.number,
      daysLeft: PropTypes.number,
      history: PropTypes.arrayOf(
        PropTypes.shape({
          amount: PropTypes.number,
          customerId: PropTypes.string,
          date: PropTypes.string,
        })
      ),
    }),
  };

  return (
    <div>
      <TableContainer component={Paper}>
        <Table aria-label="collapsible table">
          <TableHead>
            <TableRow>
              <TableCell />
              <TableCell>Name</TableCell>
              <TableCell align="left">Employment Date</TableCell>
              <TableCell align="left">Days received</TableCell>
              <TableCell align="left">Days used</TableCell>
              <TableCell align="left">Days left</TableCell>
            </TableRow>
          </TableHead>
          <TableBody>
            {employeeList.map((val, key) => (
              <Row />
            ))}
          </TableBody>
        </Table>
      </TableContainer>
    </div>
  );
}

The structure you should be using should look something like this:

function Row(props) {
   // you can access the employee object as `props.employee`
   ...
}

...

{employeeList.map((val, key) => <Row key={key} employee={val} />}

Each time you call the row function, it gives you a new row. For it to know what data should be in that row, you should be passing that data as a prop, instead of using the state. The flow of data would therefore be that the render method has a list of employees, and it calls the row builder function once with each of them, which gives back a list of rows to render.

Well, you are not giving the data to each row in the map call where you iterate over the employees. And then, instead you iterate of the whole thing again in each cell..

This should work:

const Row = ({val}) => {
  const [open, setOpen] = React.useState(false);
  const classes = useRowStyles();
  
  return (
    <React.Fragment>
      <TableRow className={classes.root}>
        <TableCell>
          <IconButton
            aria-label="expand row"
            size="small"
            onClick={() => setOpen(!open)}
          >
            {open ? <KeyboardArrowUpIcon /> : <KeyboardArrowDownIcon />}
          </IconButton>
        </TableCell>
        <TableCell component="th" scope="row">
          {val.employeeName}
        </TableCell>
        <TableCell align="left">
          {(new Date(val.employeeStartDay)).toLocaleDateString("pt-BR")}
        </TableCell>
        <TableCell align="left">
          <p>-</p>
        </TableCell>
        <TableCell align="left">
          <p>-</p>
        </TableCell>
        <TableCell align="left">
          <p>-</p>
        </TableCell>
      </TableRow>
      <TableRow>
        <TableCell style={{ paddingBottom: 0, paddingTop: 0 }} colSpan={6}>
          <Collapse in={open} timeout="auto" unmountOnExit>
            <Box margin={1}>
              <Typography variant="h6" gutterBottom component="div">
                History
              </Typography>
              <Table size="small" aria-label="purchases">
                <TableHead>
                  <TableRow>
                    <TableCell>From</TableCell>
                    <TableCell>To</TableCell>
                    <TableCell align="left">Days</TableCell>
                    <TableCell align="left">Paid</TableCell>
                  </TableRow>
                </TableHead>
                <TableBody>
                  {/* {row.history.map(() => (
                      <TableRow>
                      <TableCell component="th" scope="row"></TableCell>
                      <TableCell></TableCell>
                      <TableCell align="left"></TableCell>
                      <TableCell align="left"></TableCell>
                      </TableRow>
                    ))} */}
                </TableBody>
              </Table>
            </Box>
          </Collapse>
        </TableCell>
      </TableRow>
    </React.Fragment>
  );
};

Row.propTypes = {
  row: PropTypes.shape({
    name: PropTypes.string,
    startDate: PropTypes.string,
    shift: PropTypes.string,
    daysReceived: PropTypes.number,
    daysUsed: PropTypes.number,
    daysLeft: PropTypes.number,
    history: PropTypes.arrayOf(
      PropTypes.shape({
        amount: PropTypes.number,
        customerId: PropTypes.string,
        date: PropTypes.string,
      })
    ),
  }),
};

return (
  <div>
    <TableContainer component={Paper}>
      <Table aria-label="collapsible table">
        <TableHead>
          <TableRow>
            <TableCell />
            <TableCell>Name</TableCell>
            <TableCell align="left">Employment Date</TableCell>
            <TableCell align="left">Days received</TableCell>
            <TableCell align="left">Days used</TableCell>
            <TableCell align="left">Days left</TableCell>
          </TableRow>
        </TableHead>
        <TableBody>
          {employeeList.map((val, key) => <Row val={val} key={key}/>)}
        </TableBody>
      </Table>
    </TableContainer>
  </div>
);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM