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 trial

JavaScript

Duncan Gossage
Duncan Gossage
3,196 Points

ES6 totalPlayers and totalPoints not updating in Stats Constructor

Seeing as getting the latest from React lead to the ES6 version I decided to follow this course and learn the new way. The unfortunate thing is when old whatsisface adds var totalPlayers & var totalPoints.

On first load the totalPlayers & totalPoints are displayed, but after that when I add or remove points in the scoreboard, these variables don't change on the screen. NOW, I have checked in the DEV toolbar under the react tab and can clearly see even for the Stats element the array numbers changing. So "Stats" in the browser has the new player array with the details, it just doesn't update visually...

ES6 CODE EXAMPLE

class Stats extends Component {
  constructor(props) {
    super(props);

    this.state = {
      totalPlayers: props.players.length,
      totalPoints: props.players.reduce(function(total, player) {
        return total + player.score;
      }, 0)
    };
  }

  render() {
    return (
      <table className="stats">
        <tbody>
          <tr>
            <td>Players:</td>
            <td>{this.state.totalPlayers}</td>
          </tr>
          <tr>
            <td>Total Points:</td>
            <td>{this.state.totalPoints}</td>
          </tr>
        </tbody>
      </table>
    );
  }
}

Stats.propTypes = {
  players: PropTypes.array.isRequired
};

My problem is that whatever I do doesn't seem to work, unless I directly put the this.props directly into the template markup.

I've even tried

this.totalPlayers = props.players.length;
this.totalPoints = props.players.reduce(function(total, player) {
    return total + player.score;
}, 0);

Looking this up is a pain in the arse as well! :-S

3 Answers

Duncan Gossage
Duncan Gossage
3,196 Points

Well it turns out I can take the constructor out and replace it with this...

 class Stats extends Component {
  getTotalCount() {
    return this.props.players.length;
  }

  getTotalPoints() {
    return this.props.players.reduce(function(total, player) {
      return total + player.score;
    }, 0);
  }

  render() {
    return (
      <table className="stats">
        <tbody>
          <tr>
            <td>Players:</td>
            <td>{this.getTotalCount()}</td>
          </tr>
          <tr>
            <td>Total Points:</td>
            <td>{this.getTotalPoints()}</td>
          </tr>
        </tbody>
      </table>
    );
  }
}

Stats.propTypes = {
  players: PropTypes.array.isRequired
};
Duncan Gossage
Duncan Gossage
3,196 Points

Also there is the option of ComponentWillReveiveProps()

more information can be found here.

https://facebook.github.io/react/docs/react-component.html

Which doesn't work on first load but on subsequent updates to the props will fire. For example

class Stats extends Component {
  constructor(props) {
    super(props);

    this.totalPlayers = 0;
    this.totalPoints = 0;
  }

  componentWillReceiveProps(nextProps) {
    this.totalPlayers = nextProps.players.length;
    this.totalPoints = nextProps.players.reduce(function(total, player) {
      return total + player.score;
    }, 0);
  }

  render() {
    return (
      <table className="stats">
        <tbody>
          <tr>
            <td>Players:</td>
            <td>{this.totalPlayers}</td>
          </tr>
          <tr>
            <td>Total Points:</td>
            <td>{this.totalPoints}</td>
          </tr>
        </tbody>
      </table>
    );
  }
}

Stats.propTypes = {
  players: PropTypes.array.isRequired
};
Duncan Gossage
Duncan Gossage
3,196 Points

Well thanks you lot. I really liked this joint but the tutorials aren't up to date and you spend more time debugging as to why what you're following doesn't work. Which in a way kind of teaches you pretty well, but I could do that without a subscription.

So will be checking out, this is my final months payment.