简体   繁体   中英

Is setState running again and again in this React code?

I have created three react components and I don't know why I am getting an infinite network request and this warning: index.js:1375 Warning: Cannot update during an existing state transition (such as within render ). Render methods should be a pure function of props and state. in MenuCategory (at App.js:19) in App (at src/​index.js:5)

also a network request in MenuItems.js is getting called in a loop. I think it is due to setState but I don't know where is the error. And here is my code :

import React from "react";
import MenuCategory from "./components/MenuCategory";
import MenuItems from "./components/MenuItems";

class App extends React.Component {
  constructor(props) {
    super(props);
    this.state = { shortName: "" };
  }
  handleProps = ss => {
    if (this.state.shortName === "") {
      this.setState({ shortName: ss });
    }
    // console.log(ss, ".../PP");
  };
  render() {
    return (
      <div className="App">
        <MenuCategory callback={this.handleProps} />
        <MenuItems shortNameProp={this.state.shortName} />
      </div>
    );
  }
}

export default App;
import React from "react";

class MenuCategory extends React.Component {
  constructor(props) {
    super(props);
    this.state = { category: "", selectedCat: "" };
  }
  async UNSAFE_componentWillMount() {
    const url = "http://stream-restaurant-menu-svc.herokuapp.com/category";
    await fetch(url)
      .then(data => data.json())
      .then(element => {
        this.setState({ category: element });
      });
  }

  menuCat = () => {
    let cat = this.state.category;
    // console.log(cat, "...Cat", this.state.selectedCat, "...Cat");

    if (this.state.selectedCat !== "") {
      this.props.callback(this.state.selectedCat);
    }

    return cat.map(items => {
      return (
        <li
          key={items.short_name}
          onClick={() => this.setState({ selectedCat: items.short_name })}
        >
          {items.name}
        </li>
      );
    });
  };
  render() {
    return <div>{this.state.category.length > 0 ? this.menuCat() : null}</div>;
  }
}
export default MenuCategory;
import React from "react";

class MenuItems extends React.Component {
  constructor(props) {
    super(props);
    this.state = { catItems: "", items: "" };
  }
  renderItems = () => {
    let shortName = this.props.shortNameProp;
    if (shortName !== "") {
      const url =
        "https://stream-restaurant-menu-svc.herokuapp.com/item?category=" +
        shortName;
      fetch(url)
        .then(data => data.json())
        .then(element => {
          this.setState({ items: element });
        });
    }
    if (this.state.items !== "") {
      let selectedMenu = this.state.items;
      console.log(selectedMenu);

      return selectedMenu.map(item => {
        return <div key={item.name}> {item.name}</div>;
      });
    }
  };
  render() {
    return <div>{this.renderItems()}</div>;
  }
}
export default MenuItems;

Let's call App a parent and MenuCategory a child.
Let's denote a function call as the '->' sign.

There is an infinite loop formed like that:

child.render -> child.menuCat -> child.props.callback -> parent.handleProps -> parent.setState -> parent.render -> child.render .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM