【问题标题】:Is setState running again and again in this React code?setState 是否在这个 React 代码中一次又一次地运行?
【发布时间】:2020-01-10 19:30:08
【问题描述】:

我已经创建了三个 react 组件,但我不知道为什么我会收到无限网络请求和这个警告:index.js:1375 警告:在现有状态转换期间无法更新(例如在render 内)。渲染方法应该是 props 和 state 的纯函数。 在 MenuCategory 中(在 App.js:19) 在应用程序中(在 src/​index.js:5)

MenuItems.js 中的网络请求也被循环调用。我认为这是由于 setState 但我不知道错误在哪里。 这是我的代码:

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;

【问题讨论】:

  • 它可以,如果callback 周围的if 条件执行/它们的条件为真。为什么将相同的数据存储在两个都是本地状态的地方?为什么不将状态作为道具传递给孩子呢?这将有助于消除其价值可能存在差异的错误
  • 既然你在做异步的东西,就用componentDidMount而不是UNSAFE_componentWillMount。此外,在MenuItem 中,无限循环是因为renderItems 在获取回调中调用setState。这将触发重新渲染,这将触发renderItems的调用,它调用setState,这将触发重新渲染等等等等。只需调用一次fetch,例如componentDidMount并存储状态的项目。在渲染中,只需渲染一个加载微调器或一些加载消息,直到定义 this.state.items

标签: javascript reactjs


【解决方案1】:

我们叫App家长和MenuCategory一个孩子。结果 让我们表示一个函数调用作为'-&gt;'符号。 P>

有形成这样一个无限循环:

child.render -&gt; child.menuCat -&gt; child.props.callback -&gt; parent.handleProps -&gt; parent.setState -&gt; parent.render -&gt; child.render.

【讨论】:

    猜你喜欢
    • 2016-03-14
    • 2021-08-23
    • 1970-01-01
    • 1970-01-01
    • 2022-11-05
    • 1970-01-01
    • 1970-01-01
    • 2020-10-16
    • 1970-01-01
    相关资源
    最近更新 更多