You rewrite the context of the class method when you pass it to props like this because of JS OOP system. So to make it work there are several approaches:
1) This is not so good because bind always returns new function and your component will re-render even if there are no updates in props
import React, { Component } from 'react'; import './App.css'; class App extends Component { render() { return ( <div className="App"> <StreetFighter /> </div> ); } } class StreetFighter extends Component { constructor(props) { super(props); this.state = { characters: [ 'Chun-Li', 'Guile', 'Ryu', 'Ken', 'E.Honda', 'Dhalsim', ], }; } render() { let characters = this.state.characters; characters = characters.map((char, index) => { return ( <Character char={char} key={index} onDelete={this.onDelete.bind(this)} /> ); }); return ( <div> <p>Street Fighter Characters</p> <ul>{characters}</ul> </div> ); } onDelete(chosenCharacter) { let updatedCharactersList = this.state.characters.filter( (char, index) => { return chosenCharacter !== char; } ); this.setState({ characters: updatedCharactersList, }); } } class Character extends Component { render() { return ( <li> <div className="character"> <span className="character-name">{this.props.char}</span> <span className="character-delete" onClick={this.handleDelete.bind(this)} > x </span> </div> </li> ) }; handleDelete() { this.props.onDelete(this.props.char); } } export default App;
2) In my code I use arrow functions as class properties for such cases (it’s one of the most common solutions, I think)
class Character extends Component { render() { return ( <li> <div className="character"> <span className="character-name">{this.props.char}</span> <span className="character-delete" onClick={this.handleDelete} > x </span> </div> </li> ) }; handleDelete = () => { this.props.onDelete(this.props.char); } }