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 trialDuncan Croucher
9,709 PointstotalPoints doesn't update when the user increases or decreases the counter for a player
Hi,
I am running this locally using React App, so slightly different to the way the video does it, but everything has worked so far for me, a be it with a little googling and figuring out for myself.
However i am stuck with this, my code looks the same as on screen and in the download files, but the totalPoints doesn't update.
totalPoints = this.props.players.reduce(function (total, player) {
return total + player.score;
}, 0);
The totalPoints correctly displays, but doesn't get updated when the user changes the score using the + or - buttons
5 Answers
Mike Jensen
11,718 PointsCan you post your code for how you update the state when a player's individual score changes? If the total points shown is initially correct, and a player's individual score also seems to update in response to the +/- buttons being clicked, you may not be updating your state correctly.
Here is my example (also using a local create-react-app, with components in separate files):
onScoreChange(index, delta) {
const player = [...this.state.players][index]
player.score += delta
this.setState(player)
}
Duncan Croucher
9,709 PointsHi There,
Thanks for responding.
My code is this:
onScoreChange = (index, delta) => {
this.setState(prevState => {
return {
score: prevState.players[index].score += delta
};
});
};
I have tried you code snippet and this didn't work for me either. But my understanding is lacking it seems, having now looked back at this, so think i will run through this bit of the course again anyway.
Mike Jensen
11,718 PointsWhere are you defining onScoreChange
?
This should be defined in the nearest common ancestor of the components which are passed player information.
onScoreChange should then be passed in to a property as a callback from the ancestor component, all the way through the the counter component where the click event happens.
In my app this looks a little like this:
//App.js
...
onScoreChange() {
... code here
}
render() {
...
<Player
onScoreChange={(delta) => this.onScoreChange(index, delta)}
...
/>
}
//Player.js
...
render() {
...
<Counter
score={this.props.score}
onChange={this.props.onScoreChange}
/>
}
// Counter.js
...
render() {
...
<button className="counter-action decrement" onClick={() => this.props.onChange(-1)}> - </button>
}
Here is the reference article which describes how state should be lifted up to the nearest common ancestor, and the use of callbacks to pass requests for mutation back up through the component cascade:
Duncan Croucher
9,709 PointsHi Again,
I have managed to fix this issue, but to be honest i don't know why it works and the original way didn't. I suspect its something to do with 'this' and scope, but not sure.
The fix was to take the values from TotalPlayers and TotalPoints and put them directly into the <td>, rather than calling them in the <td>
Original:
<tbody>
<tr>
<td>Players:</td>
<td>{this.totalPlayers}</td>
</tr>
<tr>
<td>Total Points:</td>
<td>{this.totalPoints}</td>
</tr>
</tbody>
Fix:
<tbody>
<tr>
<td>Players:</td>
<td>{this.props.players.length}</td>
</tr>
<tr>
<td>Total Points:</td>
<td>{this.props.players.reduce(function (total, player) {
return total + player.score;
}, 0)}</td>
</tr>
</tbody>
Mike Jensen
11,718 PointsHi Duncan,
Could you post your full original code for your Stats component?
Here is mine for example:
import React, { Component } from 'react'
import PropTypes from 'prop-types'
export default class Stats extends Component {
render() {
const totalPlayers = this.props.players.length
const totalPoints = this.props.players.reduce((accumulator, player) => accumulator + player.score, 0)
return (
<table className="stats">
<thead></thead>
<tbody>
<tr>
<td>Players:</td>
<td>{totalPlayers}</td>
</tr>
<tr>
<td>Total points:</td>
<td>{totalPoints}</td>
</tr>
</tbody>
</table>
)
}
}
Stats.propTypes = {
players: PropTypes.array.isRequired
}
Duncan Croucher
9,709 PointsHi Mike,
I have worked out where i have gone wrong from your code example. I had my totalPlayers and totalPoints variables in the wrong place in my code.
This all now works fine.
Thank you very much for all your help.
Duncan Croucher
9,709 PointsDuncan Croucher
9,709 PointsUpdate:
This is also the same for adding and removing users, in the next video. The users are added and removed fine, but the playters stat is not updated.