Reputation: 505
I'm rendering an array of values and I have a two buttons, one to Add
and another to Remove
. Everything works the way it should but when I click Remove
, the element in the correct index gets removed from the array but when it renders again, it removes the last entry, and not the entry at that specific index.
For example: (left side is webpage, right side is console)
Currently the array is ["hello", "world", "everyone"]
and let's say I want to remove "world"
and I click the Remove
button next to it, the array updates correctly (I did a console.log) and it becomes ["hello", "everyone"]
, it re-renders but it shows it as if the array was ["hello", "world"]
and renders it incorrectly:
I'm not sure what I did incorrectly with my code as the array gets updated correctly and everything else seems to be okay.
childChange: function(name, valid, value) {
this.state.values = this.props.values;
var pattern = /[0-9]+/; // Using regex to find last digits from 0-9
var match = name.match(pattern); // Update state
var i = parseInt(match); // Parse char into int
// console.log(match);
this.state.values[i] = value;
this.setState(this.state);
this.props.callback( // Call parent callback
this.props.name,
this.props.node.valid(this.state.values),
this.state.values
);
},
addEmptyItem: function() {
this.state.values = this.props.values;
this.state.values.push("");
this.setState(this.state);
},
removeItem: function(ev) {
console.log(ev.currentTarget.dataset.index);
var i = parseInt(ev.currentTarget.dataset.index);
this.state.values = this.props.values;
this.state.values.splice(i,1);
console.log(this.state.values);
this.setState(this.state.values);
},
render: function() {
var that = this;
console.log("===RENDER===");
return (
<div id = "form">
{this.props.values.map(function(v, i) {
return (
<div>
{(that.props.node.get().constructor.name === "Parent") ?
<ParentComponent
name={that.props.name + i}
key={i}
timer={that.props.timer}
callback={that.childChange}
values={v}
newParent={that.props.node.get()}
/>
:
<div>
<NodeComponent
name={that.props.name + i}
key={i}
timer={that.props.timer}
callback={that.childChange}
value={v}
newNode={that.props.node.get()}
/>
</div>
}
<button data-index={i} onClick={that.removeItem}>Remove
</button>
</div>
)
})}
<button onClick={() => that.addEmptyItem()}>Add
</button>
</div>
)
}
Upvotes: 0
Views: 61
Reputation: 625
Change your function to look like this:
removeItem: function(ev) {
console.log(ev.currentTarget.dataset.index);
var i = parseInt(ev.currentTarget.dataset.index);
let values = [...this.props.values];
values.splice(i,1);
console.log(this.state.values);
this.setState(values);
}
Why? when you use react state, you never changing it directly. you might look about it in this article. what you did here, is you changed the state and then you called 'setState', that doesn't work. you should create new variable, manipulate over the new variable, and then call the setState with the new variable
Upvotes: 2