I've been beating my head against this for long enough that I'm not sure I'd even see an obvious problem.
The App has rows, and each row has cells of varying sizes. Adding rows works. Adding cells works. Deleting rows however, does not. If I click the delete button for row 0, row 2 disappears. If I click the button for row 1, row 2 disappears. Looking at the react dev tools, it appears that under the hood the right row is being deleted (in state), the right row is selected for deletion, but no matter what it doesn't render the way I would expect (if I hit delete for row 0, row 0 disappears, for example).
If I delete from the highest row down it works, but if I start at the zeroth row it won't let itself be deleted.
deleteRowButtonHandler of the App class is where I've been focusing my efforts.
deleteRowButtonHandler( e )
{
const targetRow = parseInt( e.target.id )
console.log( "TARGETING: ", targetRow )
const currentRows = this.state.rows
let newArray = []
currentRows.forEach( entry =>
{
console.log( "Looking at ", entry.id )
if( entry.id == targetRow )
console.log( 'skipping entry with id', entry.id )
else
newArray.push( entry )
})
console.log( newArray )
this.setState( {rows: newArray})
//let newRows = currentRows.filter( thisRow => {console.log( thisRow.id + ' and the target ' + targetRow);
// if( thisRow.id == targetRow )
// {
// console.log( thisRow )
// console.log( '...is the row that we are trying to delete' )
// }
// return thisRow.id !== targetRow}
//)
//this.setState( {rows: newArray}, console.log( "NEW STATE:", this.state ))
}
I've tried a few variations (filter, splice, doing it in a few lines, doing it in a lot of lines, etc) so I'm not particularly proud of that chunk of code at the moment.
https://codepen.io/philipvdg/pen/mdmmWLG is the code; any pointers in the right direction would be greatly appreciated.
Update
Speaking generally, the problem was that I (being a newbie) didn't understand that the constructor was only run once. In the constructor of a child component I had this.cells = this.props.cells and then, in the render method, called this.cells.map( ... ). Since the constructor only ever ran once, this.cells was never updated after a state change.
this.setState()should be a callable. In the commented out versionconsole.log( "NEW STATE:", this.state )is called immediately and its return value is passed tothis.setState(). Instead, you probably want something likenewState => console.log( "NEW STATE:", newState).