【问题标题】:How to handle props changes without using componentWillReceiveProps in React如何在 React 中不使用 componentWillReceiveProps 处理 props 更改
【发布时间】:2017-09-08 09:37:19
【问题描述】:

我一直在做一个用 React 编码的项目。我有一个组件集,我根据自己的要求实现了许多组件。其中许多就像一个复合组件。比如TextBox组件,有自己的标签,自己的错误信息机制和自己的输入过滤器等等。而且,你知道,组件有props来管理某事。

每次更新我的组件视图(渲染)时,我都会使用componentWillReceiveProps 并比较道具的变化。

但是每次执行componentWillReceiveProps 方法都是如此令人反感。

有什么方法可以在不使用componentWillReceiveProps 的情况下从上到下传递道具。我不想手动比较道具更改。有什么办法可以自动完成。

当我更改父级中的道具时,我想更新所有视图,只需从上到下更改一些道具值。

我不是反应专家,性能也不是我的首要目标!

还有一点,答案不是use Redux

我正在等待您的创意方法和有用的想法。

【问题讨论】:

  • 目前尚不清楚问题出在哪里 - 如果您想要针对(可能)更新的 props 做一些特定的事情,您只需要实现 componentWillReceiveProps
  • 当我更改父容器中的道具时,我想从上到下更新所有视图。
  • 你不需要实现componentWillReceiveProps 来让你的组件反应。我不明白你的问题?
  • @Tugrul - 传播由 React 自己处理。
  • 我要再次检查我的组件。我希望如你所说,但有些奇怪,它不能那样工作。

标签: javascript reactjs redux state


【解决方案1】:

如果没有看到您正在处理的特定事情的代码,我可能会遗漏您正在做的事情......

正如其他人评论的那样,如果提供了新的 props,React 将重新渲染您的组件,无论您是否实现 componentWillReceiveProps - 实现它的唯一原因是进行某种特定的比较或设置基于新道具值的状态。

来自 React 文档(重点是我的):

componentWillReceiveProps() 在一个挂载的组件接收到新的 props 之前被调用。 如果您需要更新状态以响应 prop 更改(例如,重置它),您可以比较 this.props 和 nextProps 并在此方法中使用 this.setState() 执行状态转换。

请注意,即使 props 没有更改,React 也可能会调用此方法,因此如果您只想处理更改,请确保比较当前值和下一个值。当父组件导致您的组件重新渲染时,可能会发生这种情况。

换句话说,如果你有这样的组件:

<TextBox title={"Foo"} content={"Bar"} />

这在内部将 prop 更改传递给几个子组件,例如:

class TextBox extends React.Component {
  
  render() {
    return (
      <div className={'text-box'}>
        <Title text={this.props.title} />
        <Body text={this.props.content} />
      </div>
    );
  }
  
}

然后每次将新道具传递给&lt;TextBox&gt;&lt;Title&gt;&lt;Body&gt; 也将使用新的text 道具重新渲染,如果您只是希望通过道具更改进行更新。 React 将自动查看更改并重新渲染。 React 处理 diffing 并且应该相当有效地仅重新渲染已更改的内容。

但是,如果您有一个单独的状态值需要设置以响应道具,例如,如果您想在新道具不同的情况下在组件上显示“更改”状态(或其他),那么你可以实现componentWillReceiveProps,比如:

class TextBox extends React.Component {
  
  componentWillReceiveProps(nextProps) {
    if (this.props.content !== nextProps.content) {
      this.setState({changed: true});
    }
  }

  render() {
    
    const changed = this.state.changed ? 'changed' : 'unchanged';

    return (
      <div className={`text-box ${changed}`}>
        <Title text={this.props.title} />
        <Body text={this.props.content} />
      </div>
    );
  }
  
}

如果您想防止在不需要性能的情况下重新渲染,请按照 Andrey 的建议进行操作并使用 shouldComponentUpdate: https://facebook.github.io/react/docs/react-component.html#shouldcomponentupdate

TLDR;除非你从 props 设置组件状态,否则可能不需要通过componentWillReceiveProps运行新的 props

2018 年 2 月更新:在未来的版本中,React 将弃用 componentWillReceiveProps 以支持新的 getDerivedStateFromProps,更多信息请点击此处:https://medium.com/@baphemot/whats-new-in-react-16-3-d2c9b7b6193b

【讨论】:

    【解决方案2】:

    有几个建议:

    • 不要将 props 复制到 componentWillReceiveProps 中的状态 - 直接从 this.props 渲染
    • 如果您的组件需要性能调整(并且如果存在性能问题):

    一般的做法,如何开发类似文本框的组件是保持无状态。组件直接渲染props,并通知父组件发生变化,它不关心管理值。

    希望这会有所帮助

    【讨论】:

      【解决方案3】:

      请考虑pureComponent,它默认实现了shouldComponentUpdate,其中浅等于用于比较上一个和下一个

      尝试以下代码:

      class MyComponent extends PureComponent {...}

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-07-11
        • 1970-01-01
        • 1970-01-01
        • 2016-08-20
        • 2019-12-05
        • 2019-06-05
        相关资源
        最近更新 更多