Welcome to the Treehouse Community
Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.
Looking to learn something new?
Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.
Start your free trialHosung Kim
11,243 PointsUncaught TypeError: props.removePlayer is not a function
Can someone help me figure out what is wrong with my code? I've watched the video multiple times, triple-checked my code, and I still can't seem to find what the issue is.
The React Dev Tools inspector declares the "removePlayer" function as "undefined" and upon invoking the function on clicking "X", I get an error in the console: Uncaught TypeError: props.removePlayer is not a function
const Header = (props) => {
return (
<header>
<h1>{props.title}</h1>
<span className="stats">Players: {props.totalPlayers}</span>
</header>
);
}
const Player = (props) => {
return (
<div className="player">
<span className="player-name">
<button className="remove-player" onClick={ () => props.removePlayer(props.id) }>✖</button>
{props.name}
</span>
<Counter />
</div>
);
}
class Counter extends React.Component {
constructor() {
super()
this.state = {
score: 0
};
}
incrementScore() {
this.setState( prevState => {
return {
score: prevState.score + 1
};
});
}
//You can use an arrow function to bind "this" which allows you to omit ".bind(this)" in the render method
decrementScore = () => {
//You can also wrap the object in parenthesis to omit the "return"
this.setState( prevState => ({
score: prevState.score - 1
}));
}
handleRemovePlayer = (id) => {
this.setState( prevState => {
return {
players: prevState.players.filter( p => p.id !== id )
};
});
}
render() {
return(
<div className="counter">
<button className="counter-action decrement" onClick={this.decrementScore}> - </button>
<span className="counter-score">{ this.state.score }</span>
<button className="counter-action increment" onClick={this.incrementScore.bind(this)}>+ </button>
</div>
);
}
}
class App extends React.Component {
constructor() {
super()
this.state = {
players: [
{
name: "Steven",
id: 1
},
{
name: "Treasure",
id: 2
},
{
name: "Ashley",
id: 3
},
{
name: "James",
id: 4
}
]
};
}
render() {
return (
<div className="scoreboard">
<Header
title="My Scoreboard"
totalPlayers={this.state.players.length}
/>
{/* Players List */}
{this.state.players.map( player =>
<Player
name={player.name}
id={player.id}
key={player.id.toString()}
removePlayer={this.handleRemovePlayer}
/>
)}
</div>
);
}
}
ReactDOM.render(
<App />,
document.getElementById('root')
2 Answers
Eric Agbayani
Full Stack JavaScript Techdegree Graduate 15,011 PointsHi Hosung,
class App extends React.Component {
constructor() {
super()
this.state = {
players: [
{
name: "Steven",
id: 1
},
{
name: "Treasure",
id: 2
},
{
name: "Ashley",
id: 3
},
{
name: "James",
id: 4
}
]
};
}
render() {
return (
<div className="scoreboard">
<Header
title="My Scoreboard"
totalPlayers={this.state.players.length}
/>
{/* Players List */}
{this.state.players.map( player =>
<Player
name={player.name}
id={player.id}
key={player.id.toString()}
removePlayer={this.handleRemovePlayer}
/>
)}
</div>
);
}
}
From my understanding of react, you don't have the handleRemovePlayer function inside the App component. You're trying pass down a function that was created inside the counter component. Try moving the function to the App component and pass it down the children components.
Hosung Kim
11,243 PointsEric Agbayani Ohhhh of course! Thanks so much!! Totally makes sense now. I appreciate it!