hpal007
hpal007

Reputation: 313

Creating Dynamic table in react js with material ui

I am trying to create dynamic table in react-js with material-ui, you can see my approach in the sandbox link, I am not sure if it is correct way to do it, or if there is more better approach exist.

In this code I am having trouble getting all the values entered in the cell from the table, I understand how useState works but here i am not able to figure out how should I approach this so that i can handle its state efficiently .
https://codesandbox.io/s/brave-noether-zukhy?file=/demo.js

import React from "react";
import { makeStyles } from "@material-ui/core/styles";
import Table from "@material-ui/core/Table";
import TableBody from "@material-ui/core/TableBody";
import TableCell from "@material-ui/core/TableCell";
import TableContainer from "@material-ui/core/TableContainer";
import TableRow from "@material-ui/core/TableRow";
import Paper from "@material-ui/core/Paper";
import InputBase from "@material-ui/core/InputBase";

const useStyles = makeStyles({
  table: {
    minWidth: 650
  }
});

export default function BasicTable() {
  const classes = useStyles();
  const parentValue = 4;
  const childValue = 1;
  const [data, setdata] = React.useState("");

  const generateTable = () => {
    let table = [];
    // Outer loop to create parent
    for (let i = 0; i < parentValue; i++) {
      let children = [];
      //Inner loop to create children
      for (let j = 0; j < childValue; j++) {
        children.push(
          <td>
            <InputBase
              defaultValue="TextInput"
              Value={data}
              onChange={(e) => {
                setdata(e.target.value);
              }}
            />
          </td>
        );
      }

      table.push(
        <TableRow key={i}>
          <TableCell>{children}</TableCell>
        </TableRow>
      );
      console.log(table);
      console.log(data);
    }
    return table;
  };

  return (
    <TableContainer component={Paper}>
      <Table className={classes.table} aria-label="simple table">
        <TableBody>{generateTable()}</TableBody>
      </Table>
    </TableContainer>
  );
}

Upvotes: 0

Views: 1427

Answers (1)

Damien Monni
Damien Monni

Reputation: 1548

Use an object as your state:

useState(() => {
  let finalState = {};
  for (let i = 0; i < parentValue; i++) {
   for (let j = 0; j < childValue; i++) {
     if (finalState[i]) {
       finalState[i] = {...finalState[i], [j]: ''};
     } else {
       finalState = { ...finalState, [i]: { [j]: '' } }
     }
   }
  }
  return finalState;
})

Then you can update the correct value on Input change:

<InputBase
  value={data[i][j]}
  onChange={(e) => {
    setdata(prev => ({
      ...prev,
      [i]: {
        ...prev[i],
        [j]: e.target.value
      }
    }))
  }}
/>

Finaly you need to update your state when parentValue or childValue updates, you can use useEffect for that.

Upvotes: 0

Related Questions