【问题标题】:Maximum update depth exceeded by adding value to select element向选择元素添加值超出了最大更新深度
【发布时间】:2019-03-03 15:21:14
【问题描述】:

我用最新版本的 React 和 React Router 制作了一个简单的小应用程序。它按预期工作 - 它是一个样式指南应用程序,允许用户选择要查看的组件并选择要应用于组件的品牌。

我正在使用两个选择元素。添加value={props.component}会导致报错:

已超过最大更新深度。这可能发生在组件 在 componentWillUpdate 内重复调用 setState 或 组件更新。 React 将嵌套更新的数量限制为 防止无限循环。

<IonSelect
          value={props.component}
          onIonChange={event => props.handleComponentPick(event)}
          interface="popover"
          placeholder="Select One"
        >
          <IonSelectOption value="button">Button</IonSelectOption>
          <IonSelectOption value="card">Card</IonSelectOption>
        </IonSelect>

我没有使用 change 事件来直接改变状态——而是事件改变了 URL(使用 React Router)并且改变的路由改变了状态:

                path="/:component/:brand/"
                render={props => (
                  <DisplayComponent
                    {...props}
                    setBrandandComponentState={this.setBrandandComponentState}
                  />
                )}
              />

这个函数就像它的名字所暗示的那样:

  setBrandandComponentState = (brand, component) => {
    this.setState({
      brand: brand,
      component: component
    });
  };

我不确定什么代码与问题相关,但路由显示的组件是:

class DisplayComponent extends Component<any> {
  componentDidMount = () => {
    const match = this.props.match;
    this.props.setBrandandComponentState(
      match.params.brand,
      match.params.component
    );
    document.body.setAttribute("brand", match.params.brand);
  };

  componentDidUpdate = prevProps => {
    if (
      this.props.match.params.brand !== prevProps.match.params.brand ||
      this.props.match.params.component !== prevProps.match.params.component
    ) {
      const match = this.props.match;
      this.props.setBrandandComponentState(
        match.params.brand,
        match.params.component
      );
      document.body.setAttribute("brand", match.params.brand);
    }
  };

  render() {
    switch (this.props.match.params.component) {
      case "button":
        return <Button />;
      case "card":
        return <Card />;
      default:
        return <p>No component selected</p>;
    }
  }
}

【问题讨论】:

    标签: javascript reactjs react-router react-router-v4


    【解决方案1】:

    您在 componentDidMount 中设置您的状态,这将导致您的组件重新渲染,这是一个无限循环,因此会出现错误。如果您想在初始化时将状态设置为道具,那么您应该使用构造函数(确保调用 super):

    class DisplayComponent extends Component<any> {
      constructor(props) {
        super(props);
        const match = this.props.match;
        this.props.setBrandandComponentState(
          match.params.brand,
          match.params.component
        );
        document.body.setAttribute("brand", match.params.brand);
      };
    

    【讨论】:

    • 我想你的意思是componentDidUpdate。在 componentDidMount 中调用 setState 不会触发无限循环。
    • 将逻辑移入构造函数而不是 componentDidMount 并没有解决问题
    • 我可以理解为什么会出现问题。我无法理解的是,我是如何根据 URL 设置状态而不发生此问题的。
    • 你想用这个状态做什么?我看不到它在哪里使用,渲染只是使用道具。
    • 您不应该跟踪值或处理 URL 更改,这是 react-router 的工作。路由器应该检测到 URL 更改,它应该将您的路由与 URL 匹配并呈现您想要的组件。您是否像this 一样使用它?看起来您正在尝试为 react-router 处理的逻辑编写代码。
    猜你喜欢
    • 2020-02-29
    • 1970-01-01
    • 2020-04-18
    • 2021-06-30
    • 2021-01-05
    • 2022-01-17
    • 1970-01-01
    • 2020-07-15
    • 1970-01-01
    相关资源
    最近更新 更多