I am making a timesheet app. The index.js renders the table. The rows of the table are read from the children array. The children array reads the state to keep itself updated. AddRow() is working fine. DeleteRow() has some problem. I intend to fetch the parentNode id from the event, lookup the state's array, splice it and let children update itself - which in turn updates the render. So when a row is deleted, it is spliced from the state's array, and that in turn is updated in the children array, and that in turn is rendered. DeleteRow runs everything except the array.splice or indexOf part. I even tried a for loop, but it doesn't work. Is my approach correct?
index.js
import React from "react";
import ReactDOM from "react-dom";
import HeaderAndFirstTableRow from "./headerandfirstrow";
import TableRow from "./tablerow";
import "./styles.css";
class App extends React.Component {
constructor(props) {
super(props);
this.state = { noOfRows: [] };
this.addRow = this.addRow.bind(this);
this.deleteRow = this.deleteRow.bind(this);
this.find = this.find.bind(this);
}
addRow() {
let arr = this.state.noOfRows;
let arrLength = arr.length;
arr.push(arrLength + 1);
this.setState({
noOfRows: arr
});
}
find(arr, id) {
for (let i = 0; i < arr.length; i++) {
if (arr[i] === id) {
return i;
}
}
}
deleteRow(event) {
let arr = this.state.noOfRows;
let id = event.target.parentNode.id;
let ix = arr.findIndex(id);
arr.splice(ix, 1);
this.setState({ noOfRows: arr });
}
render() {
let children = [];
for (let i = 0; i < this.state.noOfRows.length; i++) {
children.push(
<TableRow id={this.state.noOfRows.length} delete={this.deleteRow} />
);
}
return (
<HeaderAndFirstTableRow click={this.addRow}>
{children}
</HeaderAndFirstTableRow>
);
}
}
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
headerandfirstrow.js
import React from "react";
import "./styles.css";
export default function HeaderAndFirstTableRow(props) {
function handler() {
props.click();
}
return (
<table>
<tr>
<th>Feature</th>
<th>Phase</th>
<th>Comments</th>
<th>Monday</th>
<th>Tuesday</th>
<th>Wednesday</th>
<th>Thursday</th>
<th>Friday</th>
<th>Saturday</th>
<th>Sunday</th>
<th onClick={handler}>+</th>
</tr>
{props.children}
</table>
);
}
tablerow.js
import React from "react";
import "./styles.css";
export default function TableRow(props) {
function del(e) {
props.delete(e);
}
return (
<tr id={props.id}>
<td />
<td />
<td />
<td />
<td />
<td />
<td />
<td />
<td />
<td />
<td onClick={del}>-</td>
</tr>
);
}
splice
mutates original array, you should not mutate state,
You can change to this
deleteRow(event) {
let arr = this.state.noOfRows;
let id = event.target.parentNode.id;
let filteredArray = arr.filter(val=> val !== id)
this.setState({ noOfRows: filteredArray });
}