Skip to content Skip to sidebar Skip to footer

How To Add And Remove Table Rows Dynamically In React.js

my attempt fiddle here .......... https://jsfiddle.net/techboy0007/j1eas924/ https://i.stack.imgur.com/KXFot.png

Solution 1:

You can achieve that by playing with react state. In your case you are using nested objects so you need to be carefully when you update them.

It's not a good idea to mutate your state because it can cause easily bugs or an unexpected behavior.

Look closely how the handling functions are working.

Here you have a live demo.

classAppextendsReact.Component {
  state = {
    rows: []
  };
  handleChange = idx =>e => {
    const { name, value } = e.target;
    const rows = [...this.state.rows];
    rows[idx] = {
      [name]: value
    };
    this.setState({
      rows
    });
  };
  handleAddRow = () => {
    const item = {
      name: "",
      mobile: ""
    };
    this.setState({
      rows: [...this.state.rows, item]
    });
  };
  handleRemoveRow = () => {
    this.setState({
      rows: this.state.rows.slice(0, -1)
    });
  };
  render() {
    return (
      <div><divclassName="container"><divclassName="row clearfix"><divclassName="col-md-12 column"><tableclassName="table table-bordered table-hover"id="tab_logic"
              ><thead><tr><thclassName="text-center"> # </th><thclassName="text-center"> Name </th><thclassName="text-center"> Mobile </th></tr></thead><tbody>
                  {this.state.rows.map((item, idx) => (
                    <trid="addr0"key={idx}><td>{idx}</td><td><inputtype="text"name="name"value={this.state.rows[idx].name}onChange={this.handleChange(idx)}className="form-control"
                        /></td><td><inputtype="text"name="mobile"value={this.state.rows[idx].mobile}onChange={this.handleChange(idx)}className="form-control"
                        /></td></tr>
                  ))}
                </tbody></table><buttononClick={this.handleAddRow}className="btn btn-default pull-left"
              >
                Add Row
              </button><buttononClick={this.handleRemoveRow}className="pull-right btn btn-default"
              >
                Delete Row
              </button></div></div></div></div>
    );
  }
}

render(<App />, document.getElementById("root"));

PD: If I can give you a recommendation I'd say that you need to study a little bit more about react - javascript to move forward because it would helpful to achieve things like this faster, right now you need to understand the basics pretty good.

Solution 2:

If you want to add/remove rows dynamically you can play with the state, or if you where using Redux you can play with the store.

Here's a simple example using a components local state to add and remove rows:

https://codesandbox.io/s/k302jwn44r

EDIT: fixed mutating state

importReactfrom"react";
import { render } from"react-dom";

const styles = {
  fontFamily: "sans-serif",
  textAlign: "left"
};

classAppextendsReact.Component {
  constructor(props) {
    super(props);
    this.state = {
      rows: []
    };
  }

  handleAddRow = () => {
    this.setState((prevState, props) => {
      const row = {content: "hello this is a new row!" };
      return { rows: [...prevState.rows, row] };
    });
  };

  handleRemoveRow = () => {
    this.setState((prevState, props) => {
      return { rows: prevState.rows.slice(1) };
    });
  };

  render() {
    console.log(this.state);
    return (
      <divstyle={styles}><table><tbody>
            {this.state.rows.map(row => (
              <tr><td>{row.content}</td></tr>
            ))}
            <tr><tdclassName=""onClick={this.handleAddRow}>
                (+)
              </td>
              {Boolean(this.state.rows.length) && (
                <tdonClick={this.handleRemoveRow}>(-)</td>
              )}
            </tr></tbody></table></div>
    );
  }
}

render(<App />, document.getElementById("root"));

Solution 3:

In case someone might be looking for a React hooks version, this is a sample implementation of Arnold's answer:

importReact, { useState } from"react";

constApp = () => {
  const [rows, setRows] = useState([{}]);
  const columnsArray = ["name", "id", "mobile", "date", "amount"]; // pass columns here dynamicallyconsthandleAddRow = () => {
    const item = {};
    setRows([...rows, item]);
  };

  constpostResults = () => {
    console.log(rows); // there you go, do as you please
  };
  consthandleRemoveSpecificRow = (idx) => {
    const tempRows = [...rows]; // to avoid  direct state mutation
    tempRows.splice(idx, 1);
    setRows(tempRows);
  };

  constupdateState = (e) => {
    let prope = e.target.attributes.column.value; // the custom column attributelet index = e.target.attributes.index.value; // index of state array -rowslet fieldValue = e.target.value; // valueconst tempRows = [...rows]; // avoid direct state mutationconst tempObj = rows[index]; // copy state object at index to a temporary object
    tempObj[prope] = fieldValue; // modify temporary object// return object to rows` clone
    tempRows[index] = tempObj;
    setRows(tempRows); // update state
  };

  return (
    <div><divclassName="container"><divclassName="row clearfix"><divclassName="col-md-12 column"><tableclassName="table table-bordered table-hover"id="tab_logic"><thead><tr><thclassName="text-center"> # </th>
                  {columnsArray.map((column, index) => (
                    <thclassName="text-center"key={index}>
                      {column}
                    </th>
                  ))}
                  <th /></tr></thead><tbody>
                {rows.map((item, idx) => (
                  <trkey={idx}><td>{idx + 1}</td>
                    {columnsArray.map((column, index) => (
                      <tdkey={index}><inputtype="text"column={column}value={rows[idx][column]}index={idx}className="form-control"onChange={(e) => updateState(e)}                             
                          
                        />
                      </td>
                    ))}

                    <td><buttonclassName="btn btn-outline-danger btn-sm"onClick={() => handleRemoveSpecificRow(idx)}
                      >
                        Remove
                      </button></td></tr>
                ))}
              </tbody></table><buttononClick={handleAddRow}className="btn btn-primary">
              Add Row
            </button><buttononClick={postResults}className="btn btn-success float-right"
            >
              Save Results
            </button></div></div></div></div>
  );
};

exportdefaultApp;

Solution 4:

Thanks for the answer above. Just a little bit comment on handling of 'handleChange'. Do we need to change the following

    rows[idx] = {
      [name]: value
    };

to the following for saving the data into rows:

const rowInfo = rows[idx];
rowInfo[name] = value;

Post a Comment for "How To Add And Remove Table Rows Dynamically In React.js"