Inserting new values into the array worked, but i want the table to be updated in render

this.state = {
materials: [
                {
                    material: {id: 1, label: 'm1'},
                    quantity: 2,
                    unitPrice: 12,
                    total: 0
                },
                {
                    material:  {id: 2, label: 'm2'},
                    quantity: 4,
                    unitPrice: 15,
                    total: 1
                }
            ]
}

handleOnClick(e){
        this.state.materials.push(this.state.selectedMaterialUnitID, this.state.quantity, this.state.unitPrice, this.state.total);
        console.log(this.state.materials); // this worked fine

    }
<tbody>
{materials.map((obj) => {return(
    <tr>
        <td >{obj.material.label}</td>
        <td>{obj.quantity}</td>
        <td>{obj.unitPrice}</td>
        <td>{obj.total}</td>
    </tr>
)})}
</tbody>

<Button varient={"light"} onClick={this.handleOnClick}>Add row</Button>

expected result is when the table updated and insert the new row

2 Answers

1
julekgwa On Best Solutions

Use set state setState() tutorial

official docs

handleOnClick = (e) => {

  this.setState({
    materials: [
      ...this.state.materials,
      // add an object 
      { material: this.state.selectedMaterialUnitID,
      quantity: this.state.quantity,
      unitPrice: this.state.unitPrice,
      total: this.state.total
      },
    ]
  });
}
3
Sergio Moura On

React does not know that you updated the state.

When updating states with react, use this.setState(/* new value */).

Your code should look like this:

handleOnClick(e) {
  this.setState({
    // just materials. the other keys will not be affected.
    materials: [
      ...this.state.materials,
      this.state.selectedMaterialUnitID,
      this.state.quantity,
      this.state.unitPrice,
      this.state.total,
    ]
  });

  // this will show the old state now, since updating the state is asynchronous.
  console.log(this.state.materials);
}

If you want your console.log to reflect the state after the update, you can use the second parameter of setState, like so:

handleOnClick(e) {
  this.setState({
    materials: [
      ...this.state.materials,
      this.state.selectedMaterialUnitID,
      this.state.quantity,
      this.state.unitPrice,
      this.state.total,
    ]
  },
  (state) => {
    console.log(state.materials);
  }
  );
}

I'm not sure how your .push method will work with all those extra parameters, but I hope that you got the point. If you want to add a new object to the array, just add the proper delimiters and keys.

Edit to add: Check this link on why you shouldn't update the state directly: https://reactjs.org/docs/state-and-lifecycle.html#do-not-modify-state-directly