【问题标题】:How to change/update componentWillReceiveProps to getDerivedStateFromProps in React?如何在 React 中将 componentWillReceiveProps 更改/更新为 getDerivedStateFromProps?
【发布时间】:2020-07-03 20:39:01
【问题描述】:

我知道他们不推荐使用 componentWillReceiveProps,我被要求用 getDerivedStateFromProps 替换,但他们似乎根本没有做同样的事情。 getDerived... 也不能访问这个或 setsetate。我看了很多关于转换为新方式的文章,但它不适用于我的情况,因为我没有返回对象。

componentWillReceiveProps 正在将此路径“/dashboard”推送到 this.props.history 中。

getDerivedStateFromProps 必须返回一个对象。我该怎么做?

componentDidMount() {
    // If logged in and user navigates to Login page, should redirect them to dashboard
    if (this.props.auth.isAuthenticated) {
      this.props.history.push("/dashboard");
    }
  }

  componentWillReceiveProps(nextProps) {
    if (nextProps.auth.isAuthenticated) {
      this.props.history.push("/dashboard");
    }

    if (nextProps.errors) {
      this.setState({
        errors: nextProps.errors,
      });
    }
  }

我尝试执行以下操作,但我收到一条错误消息,提示我必须返回一个对象。

  static getDerivedStateFromProps(nextProps, prevState) {
    return nextProps.auth.isAuthenticated
      ? nextProps.history.push("/dashboard")
      : { errors: nextProps.errors };
  }

编辑:我使用与原始代码相同的方法尝试了 ComponentDidUpdate,但导致崩溃。

  componentDidUpdate(prevProps, prevState) {
    if (prevProps.auth.isAuthenticated) {
      this.props.history.push("/dashboard");
    }

    if (prevState.errors) {
      this.setState({
        errors: prevProps.errors,
      });
    }
  }

但这种方式似乎有效。到目前为止没有错误。但我不确定我是否理解上面的代码失败的原因。

  componentDidUpdate(prevProps) {
    console.log(prevProps.auth, this.props.auth, this.props.history);
    if (prevProps.auth.isAuthenticated !== this.props.auth.isAuthenticated) {
      this.props.history.push("/dashboard");
    }
    console.log(this.props.history);
    if (prevProps.errors !== this.props.errors) {
      this.setState({
        errors: this.props.errors,
      });
    }
  }

【问题讨论】:

  • 你不能只使用componentDidUpdate生命周期函数并检查this.props.auth.isAuthenticated来发出导航的副作用吗?
  • 我试过了。我收到此错误“错误:超出最大更新深度。当组件在 componentWillUpdate 或 componentDidUpdate 中重复调用 setState 时,可能会发生这种情况。”
  • 您是否在其中一项功能中设置不受保护的状态? IE。不检查prevProps
  • 我用失败的代码编辑了我的帖子。还发现了一些有用的东西,但我仍然很困惑。

标签: javascript reactjs


【解决方案1】:

问题

在这个例子中,如果有任何真实的错误状态,那么你会不断地设置状态,触发另一个渲染周期,再次更新状态......冲洗并重复直到崩溃。这就是所谓的无保护状态更新。

componentDidUpdate(prevProps, prevState) {
  if (prevProps.auth.isAuthenticated) {
    this.props.history.push("/dashboard");
  }

  if (prevState.errors) {
    this.setState({
      errors: prevProps.errors, // <-- sets state and rerenders, repeatedly
    });
  }
}

解决方案

使用保护检查将先前的状态和/或道具与当前状态和/或道具进行比较,并且仅在值更改时更新状态一次。这就是第二个示例没有创建状态更新周期的原因。

componentDidUpdate(prevProps) {
  console.log(prevProps.auth, this.props.auth, this.props.history);
  if (prevProps.auth.isAuthenticated !== this.props.auth.isAuthenticated) {
    this.props.history.push("/dashboard");
  }

  console.log(this.props.history);
  if (prevProps.errors !== this.props.errors) { // <-- Only update error state if value different
    this.setState({
      errors: this.props.errors,
    });
  }
}

反应文档componentDidUpdate

componentDidUpdate(prevProps) {
  // Typical usage (don't forget to compare props):
  if (this.props.userID !== prevProps.userID) {
    this.fetchData(this.props.userID);
  }
}

可以立即致电setState()componentDidUpdate(),但请注意 它必须被包裹在一个条件中,就像上面的例子一样,或者 你会导致一个无限循环。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-09-08
    • 2023-03-19
    • 2020-02-01
    • 2021-08-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多