I have a simple form, where I would like to remove the selected item on remove button click. I'm partially removing the desired item, but if I remove the middle item, it also removes the last item. If I remove the first item, it removes the entire array.
code here:
import React from "react";
import ReactDOM from "react-dom";
import "./styles.css";
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
data: ["Saab", "Volvo", "BMW"],
editMode: false,
rulesTerm: ""
};
}
handleInput = e => {
let value = e.target.value;
let name = e.target.name;
console.log(name);
console.log(value);
this.setState(prevState => ({
data: {
...prevState.data,
[name]: value
}
}));
};
handleFormSubmit = e => {
e.preventDefault();
const { data } = this.state;
console.log(data);
};
removeRule = (e, index) => {
e.preventDefault();
const { data } = this.state;
console.log("removed", data.splice(index));
this.setState({
data: data,
rulesTerm: ""
});
};
render() {
return (
<div className="App">
<div>
{!this.state.editMode ? (
<button onClick={() => this.setState({ editMode: true })}>
edit
</button>
) : (
<div>
<button onClick={() => this.setState({ editMode: false })}>
cancel
</button>
<button onClick={this.handleFormSubmit}>submit</button>
</div>
)}
</div>
<React.Fragment>
{this.state.data.map((rule, index) =>
this.state.editMode ? (
<form onSubmit={this.handleFormSubmit}>
<React.Fragment>
<input
onChange={this.handleInput}
type="text"
placeholder="Cars"
name={rule}
defaultValue={rule}
key={index}
/>
<button onClick={event => this.removeRule(event, index)}>
Remover
</button>
</React.Fragment>
</form>
) : (
<p key={rule}> - {rule} </p>
)
)}
</React.Fragment>
</div>
);
}
}
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
Any help? Thank you!
When using splice
, you need to pass in the number of elements to delete.
If deleteCount is omitted, or if its value is equal to or larger than array.length - start (that is, if it is equal to or greater than the number of elements left in the array, starting at start), then all of the elements from start through the end of the array will be deleted.
One solution would be to convert your deleting function into a curried function, which will first receive the index
when called once, and then the event.
You can filter out your element using the callback version of setState
and filtering out the element with the same index :
removeRule = index => event => {
this.setState(prev => ({
data: prev.data.filter((el, i) => i !== index),
rulesTerm: ""
}));
};
You could also indicate your splice
method that it only requires to remove a single element :
removeRule = index => event => {
this.setState(prev => ({
data: prev.data.splice(index, 1),
rulesTerm: ""
}));
};
Your function binding in the JSX will now look like the following :
<button onClick={this.removeRule(index)}>
Remover
</button>
In your case I would use a filter, and pass the rule as an argument:
<React.Fragment>
{this.state.data.map((rule, index) =>
this.state.editMode ? (
<form onSubmit={this.handleFormSubmit}>
<React.Fragment>
<input
onChange={this.handleInput}
type="text"
placeholder="Cars"
name={rule}
defaultValue={rule}
key={index}
/>
<button onClick={event => this.removeRule(event, rule)}>
Remover
</button>
</React.Fragment>
</form>
) : (
<p key={rule}> - {rule} </p>
)
)}
</React.Fragment>
Than in your removeRule function:
removeRule = (e, rule) => {
e.preventDefault();
const { data } = this.state;
const newData = data.filter(item => item !== rule);
console.log("removed");
this.setState({
data: newData,
rulesTerm: ""
});
};
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.