How To Add And Remove Table Rows Dynamically In React.js
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"