Problem making Camper Leaderboard render new data

I’m very new to React, and this feels like a problem where I’m missing something fundamental.

I’ve set up the leaderboard, and it works fine with its initial state and properties. The issue is that when I trigger the function to switch the data the leaderboard displays—which is a simple function that changes the url from which the leaderboard’s data is populated—two things happen:

  1. I have to click twice for the url to change to the new url. On this first click, it stays the same.
  2. Even when the URL changes, the application does not update, and no new information is displayed.

I feel like there’s something about lifecycles I’m just missing here. Could anyone give me a shove in the right direction? I’d very much appreciate it.

Here is the pen:

Haiii! I think your code is actually working without any changes—if you wait for a bit between clicks you would eventually getting the desired habit that you want (I suppose that’s not desirable in a user’s perspective)!

I don’t have a lot of experience with using shouldComponentUpdate and componentWillUpdate—but I don’t think those lifecycles are needed in your case and would only complicate your logic.

One thing that I find helpful to keep in mind when I just started using React is that changes to a state that is being rendered inside the render() method will cause a re-render. If we put it into the context of your project:

  • The app should initially display a list of all campers:
    componentDidMount() {
        self = this;
        $.getJSON(recentUrl, function(x) {
            self.setState({campers: x});
            // Since this.state.campers is inside the render() method, once the async API calls finishes this setState() method will be called, causing a re-render and showing the "recent" list
        });
    }
  • The method will simply make an API call again and set this.state.campers to the new list received in order to cause a re-render:
    switchAllTime() {
        $.getJSON(allTimeUrl, function(x) {
            self.setState({
                campers: x,
                url: allTimeUrl
            });
        });
    };
  
    switchRecent() {
        $.getJSON(recentUrl, function(x) {
            self.setState({
                campers: x,
                url: recentUrl
            });
        });
    };

You can now get rid of componentWillMount and shouldComponentUpdate and your app should be working!

It is worth noting that there are other ways to structure this that will give you the same result, and that there are little things you may consider doing such as making sure that API calls are only made when the current URL is different to the new URL, or refactoring your code by having a single function for both onClick triggers.

In addition, once you are a bit more comfortable with the basics I would suggest moving away from Codepen and use Glitch (there are various React boilerplates that you can remix) or, better still,create-react-app instead. Using ES6 syntax will also make your React code much cleaner, too!

I hope that’s reasonably easy to follow helps! Good luck. :slight_smile:

1 Like

Thank you so much! I wish there was a way to give more thanks. This advice was incredibly helpful.

1 Like