jarivak
jarivak

Reputation: 858

How to update the value present inside array of array in reactjs

Working Code :https://codesandbox.io/s/broken-https-2i454?file=/src/App.js

I'm using Material UI in my reactjs project and I'm trying the update the value entered inside a textfield of a table using onChange function for the textfield, currently the value is present inside an array of array,I want to update the componentQuantity , I'm aware of passing the event to get the event.target.value , but what is the correct way to update the specific value of the textfield present inside a array of array. Please someone help me out here.


class TabData extends Component {
  constructor(props) {
    super(props);
    this.state = {
      loading: true,
      data: [
        {
          BomComponentCode: "345543",
          BomComponentName: "COMP1",
          BomComponentRefUOM: "gm",
          rowId: 0,
          consumptionBatchNumbers: [
            {
              componentBatchNumber: "20",
              componentQuantity: 2
            },
            {
              componentBatchNumber: "21",
              componentQuantity: 3
            }
          ]
        },
        //2nd cloumn
        {
          BomComponentCode: "5543",
          BomComponentName: "COMP2",
          BomComponentRefUOM: "KG",
          rowId: 1,
          consumptionBatchNumbers: [
            {
              componentBatchNumber: "22",
              componentQuantity: 4
            },
            {
              componentBatchNumber: "23",
              componentQuantity: 5
            }
          ]
        }
      ],
      renderState: false
    };
  }

  handleUpdate = (index, Code) => {
    
    this.setState({
      renderState: Code
      
    });
  };

  handleChange = (e) => {
   
    console.log(e.target.value)
  };
  render() {
    const { classes } = this.props;
    const { data, renderState } = this.state;
    return (
      <div className={classes.list}>
        <React.Fragment>
          <Grid
            item
            xs={12}
            sm={12}
            md={12}
            className={classes.grid}
            style={{ paddingLeft: "0" }}
          >
            <p variant="h6" className={classes.font}>
              Table Details
            </p>
            <span className={classes.borders}></span>
          </Grid>

          <div>
            <TableContainer component={Paper} className={classes.paper}>
              <Table className={classes.table} aria-label="collapsible table">
                <TableHead>
                  <TableRow>
                    <TableCell> Number</TableCell>
                    <TableCell> Text</TableCell>
                    <TableCell>UOM</TableCell>
                    <TableCell> Batch </TableCell>
                    <TableCell> Quantity</TableCell>
                    <TableCell>Actions</TableCell>
                  </TableRow>
                </TableHead>

                <TableBody>
                  <React.Fragment>
                    {data.map((item, i) => (
                      <React.Fragment>
                        <TableRow key={i}>
                          <TableCell scope="row" align="left">
                            {item.BomComponentCode}
                          </TableCell>
                          <TableCell align="left">
                            {item.BomComponentName}
                          </TableCell>
                          <TableCell align="left">
                            {item.BomComponentRefUOM}
                          </TableCell>
                          <TableCell>
                            {item.consumptionBatchNumbers.map((row, i) => (
                              <div key={i}>
                                <TableCell align="left">
                                  {row.componentBatchNumber}
                                </TableCell>
                              </div>
                            ))}
                          </TableCell>
                          {renderState === item.BomComponentCode ? (
                            <TableCell align="left">
                              {item.consumptionBatchNumbers.map((row, indi) => (
                                <div key={indi}>
                                  <input
                                    // value={row.componentQuantity}
                                    onChange={(e) =>
                                      this.handleChange(e)
                                    }
                                    defaultValue={row.componentQuantity}
                                  />
                                </div>
                              ))}
                            </TableCell>
                          ) : (
                            <TableCell align="left">
                              {item.consumptionBatchNumbers.map((row, indi) => (
                                <div key={indi}>
                                  <TableCell align="left">
                                    {row.componentQuantity}
                                  </TableCell>
                                </div>
                              ))}
                            </TableCell>
                          )}

                          <TableCell>
                            <button
                              onClick={() =>
                                this.handleUpdate(i, item.BomComponentCode)
                              }
                            >
                              Update
                            </button>
                          </TableCell>
                        </TableRow>
                      </React.Fragment>
                    ))}
                  </React.Fragment>
                </TableBody>
              </Table>
            </TableContainer>
          </div>

          <Grid container justify="center">
            <Grid
              item
              xs={4}
              sm={4}
              md={2}
              style={{
                textAlign: "center",
                padding: "1rem"
              }}
            >
              <button >Close</button>
            </Grid>
          </Grid>
        </React.Fragment>
      </div>
    );
  }
}

export default (TabData);



Upvotes: 1

Views: 68

Answers (1)

Shyam
Shyam

Reputation: 5497

To modify the value in the deeply nested array you need indexes . Once you have the indexes its easier to change the values .

Change the handleChange method to accept the row and deeply nested row's indexes.

onChange={(e) => this.handleChange(e, i, indi)}

Once you have the indexes we can deep clone the original state to create a new copy of state and mutate it directly .

 handleChange = (e, rowIndex, consumptionBatchIndex) => {
    // deep clone the data 
    const clonedData = JSON.parse(JSON.stringify(this.state.data));

    clonedData[rowIndex].consumptionBatchNumbers[
      consumptionBatchIndex
    ].componentQuantity = e.target.value;
    this.setState({
      data: clonedData
    });
  };

Now we can read the value in the input as

<input
   value={row.componentQuantity}
   onChange={(e) => this.handleChange(e, i, indi)}
/>

Upvotes: 2

Related Questions