Nancy Moore
Nancy Moore

Reputation: 2470

setState method causes infinite loop of Results in Reactjs Functions

The code displays users records from an array. I also creates an updateCount() function which counts users on content display.

I can see the count results alerted and in the console.

Now I want to display the count results and to this effect, I initialize setState() method within the updateCount function.

updateCount = userId => {
    ...some code missing
    this.setState({dataCount: count});
}

This causes infinite loop of the results due to re-rendering. Is there anyway to get the setState out of the UpdateCount() function to enable me display the count results well or any better possible approach.

Here is the Code

import React, { Component, Fragment } from "react";
import { render } from "react-dom";

class App extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      data: [],
      userCount: []
    };
  }

  componentDidMount() {
    var userId = "100";

    this.setState({
      data: [
        {
          id: "100",
          name: "Luke"
        },
        {
          id: "200",
          name: "Henry"
        },
        {
          id: "300",
          name: "Mark"
        }
      ]
    });

    this.updateCount = this.updateCount.bind(this);
  }

  updateCount = userId => {
    var count = 1;
    alert("counting: " + count);
    console.log("counting: " + count);

    this.setState({ dataCount: count });
  };

  render() {
    return (
      <span>
        <label>
          (---{this.state.dataCount}--)
          <ul>
            {this.state.data.map((person, i) => {
              if (person.id == 100) {
                //this.updateCount(person.id);

                return (
                  <div key={i}>
                    <div>
                      {person.id}: {person.name}
                    </div>
                  </div>
                );
              } else {
                this.updateCount(person.id);
              }
            })}
          </ul>{" "}
        </label>{" "}
      </span>
    );
  }
}

Upvotes: 9

Views: 20838

Answers (2)

Idan
Idan

Reputation: 5450

From ReactJS docs:

The render() function should be pure, meaning that it does not modify component state, it returns the same result each time it’s invoked, and it does not directly interact with the browser.

Since updateCount() is calling setState(), you are calling setState in render. You need to redesign your code code, possibly creating array in state and using map in render.

Using getDerivedStateFromProps might be a good idea, make sure you to use a conditional statement, else you might hit another infinite loop.

Upvotes: 9

samb102
samb102

Reputation: 1114

You are calling in your render() method this.updateCount(person.id) which do a setState. Therefore a re-rendering occurs, and then this.updateCount(person.id) is called again. And it goes on.. (infinite loop)

Upvotes: 8

Related Questions