Dudis Dudis - 2 months ago 24
Javascript Question

React HandleDelete TypeError undefined

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.

QoP QoP
Answer

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}/>
        )
    })
}