I have React component called Websites to handle state
class Websites extends React.Component {
constructor(props) {
super(props);
this.handleWebsiteDelete = this.handleWebsiteDelete.bind(this);
this.state = {
websites: this.props.websites
}
}
handleWebsiteDelete(id) {
console.log("delete")
// How to Run This Function?
// ...further code to delete id from state.websites
}
render () {
return(
<div className="row">
{
this.state.websites.map(function(website, index) {
return (
<WebsiteItem key={website.id} {...website} onDelete={this.handleWebsiteDelete}/>
)
})
}
</div>
);
}
}
Then I have React component called WebsiteItem with a function handleDelete an object:
class WebsiteItem extends React.Component {
handleDelete(e) {
e.preventDefault();
$.ajax({
method: "DELETE",
url: "/websites/" + this.props.id
})
.done(function(){
this.props.onDelete(this.props.id);
}.bind(this))
}
render() {
return (
<div className="card">
{this.props.name}
<a href="#" onClick={this.handleDelete.bind(this)}>Delete</a>
</div>
);
}
}
My goal is to delete a website from a server using ajax inside WebsiteItem component (successfully done) and run a function onDelete
inside Websites component to update the state this.state.websites
.
I can't manage to run the function with an error: Uncaught TypeError: this.props.onDelete is not a function
- I tried to play with bind(this) but not sure if I complete understand it. Thank you.
You almost got it right.
You have to bind
the callback function you are passing to this.state.websites.map()
to your component instance.
In order to do it, you have to pass the context as the second argument to .map()
{
this.state.websites.map(function(website, index) {
return (
<WebsiteItem key={website.id} {...website} onDelete={this.handleWebsiteDelete}/>
)
},this)
}
Or use arrow functions
{
this.state.websites.map((website, index) => {
return (
<WebsiteItem key={website.id} {...website} onDelete={this.handleWebsiteDelete}/>
)
})
}