1

I am struggling with React and the lifecycles. I try to implement a very simple Next button which shows the next page with a next set of items. When I change manually the state offset to 3, the page is rendered correctly with the next items. But when I use setState by using a button, the new items are not loaded. I assume it has something to do with lifecycles, but I don't get it yet.

class EventsListContainer extends React.Component {
  state = {
    limit: 3,
    offset: 0
  };

  componentDidMount() {
    const { loadEvents } = this.props;
    const { limit, offset } = this.state;
    loadEvents(limit, offset);
  }

  onClickHandler = () => {
    this.setState({ limit: 3, offset: 3 });
    const { limit, offset } = this.state;
    loadEvents(limit, offset);
  };

  render() {
    const { events, isLoggedIn } = this.props;

    return (
      <div>
        <EventsList events={events} isLoggedIn={isLoggedIn} />
        <Button onClick={() => this.onClickHandler()}>Next</Button>
      </div>
    );
  }
}
Rogier
  • 905
  • 1
  • 10
  • 25
  • 2
    what does loadEvents do? Typically you want to have a prop that is a function. This function is then called by the handler that is rendering the component. So state is set, props function called, handler does business logic and then re-renders the component. What I can see here, you just set the state which has no side effects. – Sandra Willford Feb 27 '19 at 14:04
  • You are destructuring `this.state` before the update from `setState()` has gone through. Remember that setState is asynchronous. – Chris Feb 27 '19 at 14:05
  • loadEvents is a Redux action which calls a database endpoint and retrieves a list of events. I've moved the button to the presentational component and and calling onClickHandler by props, the state are changed, but the page is not rendered with the new items. – Rogier Feb 27 '19 at 14:39

1 Answers1

5

The call on setState is asynchronous. You can fix it by adding a callback e.g.

this.setState({ limit: 3, offset: 3 }, () => loadEvents(this.state.limit, this.state.offset));
Murat Karagöz
  • 35,401
  • 16
  • 78
  • 107
  • This seems reasonable, but when I implemented this fix, the page is still not rendered, while the state has been changed. – Rogier Feb 27 '19 at 14:40
  • @Rogier A call on `setState` will result on a re-render unless you explicitly disabled it in `shouldComponentUpdate`. Other than that you should look into your `loadEvents` function and find the culprit there. – Murat Karagöz Feb 27 '19 at 14:47