在ReactJs中使用标头创建动态表的问题

问题描述

我正在尝试根据带有标题的输入(行数和列数)创建动态表, 并将其值存储在字典变量列表中,其中键将是标题数据,而值将是行数据。

问题: 我的行部分工作正常,但是当我尝试让+1行(我想为标题考虑)时,当rowValue大于1时我面临问题 为了更好地理解,请点击下面的沙盒链接

https://codesandbox.io/s/serene-dhawan-6xod9?file=/src/demo.js

   // let rowVariable = 1;
    // rowVariable = rowValue + rowVariable
    let table = [];
    // Outer loop to create parent
     // for (let i = 0; i < rowVariable ; i++) { or
    // for (let i = 0; i < rowValue ; i++) {
    for (let i = 0; i < rowValue +1 ; i++) {

在沙盒中第77行的循环上方,如果我从rowValue删除+1,代码对于行部分工作正常,并且我没有任何行用于标头,但是使用+1我得到标头(在认行上) ),但是当我增加rowValue时,会得到多行。

我无法调试导致此问题的原因。 感谢您的帮助。

CODE:

import React,{ Fragment,useState,useRef,useEffect } from "react";
// Material-ui imports
import { fade,withStyles } from "@material-ui/core/styles";
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";
import TextField from "@material-ui/core/TextField";
const useStyles = makeStyles({
  table: {
    minWidth: 650
  }
});
const BootstrapInput = withStyles((theme) => ({
  root: {
    "label + &": {
      marginTop: theme.spacing(3)
    }
  },input: {
    borderRadius: 4,position: "relative",backgroundColor: theme.palette.common.white,border: "1px solid #ced4da",fontSize: 16,width: "60%",padding: "5px 6px",transition: theme.transitions.create(["border-color","Box-shadow"]),"&:focus": {
      BoxShadow: `${fade(theme.palette.primary.main,0.25)} 0 0 0 0.2rem`,borderColor: theme.palette.primary.main
    }
  }
}))(InputBase);

export default function DataTabelVariable(props) {
  // Table
  const classes = useStyles();
  const [rowValue,setRowValue] = useState(0);
  const [columnsValue,setColumnsValue] = useState(0);
  const [tableCellsData,setTableCellsData] = useState();
  const [tableArrayData] = useState([[]]);
  const ref = useRef(null);

  const getUniqueKeyFromArrayIndex = (rowNum,columnNum) => {
    return `${rowNum}-${columnNum}`;
  };

  const onChangeHandler = (e) => {
    setTableCellsData({
      ...tableCellsData,[e.target.name]: e.target.value
    });
    let [row,col] = e.target.name.split("-");
    row = parseInt(row);
    col = parseInt(col);

    if (!tableArrayData[row]) {
      tableArrayData[row] = [];
      tableArrayData[row].push([]);
    }
    tableArrayData[row][col] = e.target.value;
    props.value(tableArrayData);
  };

  const generateTable = () => {
    // let rowVariable = 1;
    // rowVariable = rowValue + rowVariable
    let table = [];
    // Outer loop to create parent
     // for (let i = 0; i < rowVariable ; i++) { or
    // for (let i = 0; i < rowValue ; i++) {
    for (let i = 0; i < rowValue +1 ; i++) {
      let children = [];
      //Inner loop to create children
      for (let j = 0; j < columnsValue; j++) {
        children.push(
          <td>
            <BootstrapInput
              name={getUniqueKeyFromArrayIndex(i,j)}
              onChange={onChangeHandler}
            />
          </td>
        );
      }
      table.push(
        <TableRow key={i}>
          <TableCell>{children}</TableCell>
        </TableRow>
      );
    }
    return table;
  };

  return (
    <Fragment>
      <div>
        <h5>Select Row number and Columns number</h5>
        <div className={"rowColumnsNumber"} style={{ marginTop: 20 }}>
          <TextField
            id="Row-number"
            label="Row(s)"
            type="number"
            InputLabelProps={{ shrink: true }}
            inputProps={{ min: "0",max: "1000",step: "1" }}
            onChange={(e) => setRowValue(e.target.value)}
            variant="outlined"
          />
          <TextField
            id="Columns-number"
            label="Columns(s)"
            type="number"
            inputProps={{ min: "0",step: "1" }}
            InputLabelProps={{ shrink: true }}
            onChange={(e) => setColumnsValue(e.target.value)}
            variant="outlined"
          />
        </div>
        <br />
        <div className={"TableContainer"}>
          <TableContainer component={Paper}>
            <Table className={classes.table} aria-label="simple table">
              <TableBody ref={ref}>{generateTable()}</TableBody>
              {/* <TableBody> {generateTable()}</TableBody> */}
            </Table>
          </TableContainer>
        </div>
      </div>
    </Fragment>
  );
}

解决方法

在以上代码中,您分别将第112和121行中的rowValuecolumnsValue的值设置为字符串而不是整数。原因是e.target.value将为您提供类似于“ 1”的字符串,而不是整数1。因此,for循环中的条件为true,因为它将i的值与ASCII值“ 1”进行比较(即49)。因此,您必须使用e.target.valueint的值转换为parseInt(e.target.value,10),它将按预期工作。