如何在不使用React中的componentWillReceiveProps的情况下处理props更改

时间:2017-04-12 14:24:19

标签: javascript reactjs redux state

我一直在研究用React编码的项目。我有一个组件集,我为我自己的要求实现了许多组件。其中许多行为就像一个复合组件。例如, TextBox 组件,有自己的标签,自己的错误消息机制和自己的输入过滤器等。而且,你知道,组件有道具来管理......

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

但每次实施componentWillReceiveProps方法都是如此令人厌恶。

有没有办法在不使用componentWillReceiveProps的情况下从上到下传递道具。我不想手动比较道具变化。有没有办法自动完成。

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

我不是反应专家,表现也不是我的第一个目的!

答案不是use Redux还有一件事!

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

3 个答案:

答案 0 :(得分:12)

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

正如其他人所评论的那样,如果提供了新的道具,React将重新渲染你的组件,无论你是否实现componentWillReceiveProps - 实现它的唯一理由是进行某种特定的比较或根据新的道具价值设定州。

来自React docs(强调我的):

  

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

     

请注意,即使道具没有更改,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>
    );
  }

}

然后,每次将新道具传递给<TextBox>时,<Title><Body>也会使用新的text道具进行重新渲染,并且其中没有理由使用componentWillReceiveProps,如果您只是想要使用道具更改进行更新。 React将自动查看更改并重新呈现。并且React处理diffing并且应该相当有效地重新渲染已经改变的东西。

但是,如果你有一个单独的状态值需要设置以响应道具,例如,如果你想显示一个&#34;更改&#34;如果新道具不同,组件上的状态(或其他),则可以实现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的建议并使用shouldComponentUpdatehttps://facebook.github.io/react/docs/react-component.html#shouldcomponentupdate

<强> TLDR;除非您从道具设置组件状态,否则可能无需通过componentWillReceiveProps

运行新道具

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

答案 1 :(得分:2)

有一些建议:

  • 不要在componentWillReceiveProps中将道具复制到州内 - 只需直接从this.props
  • 呈现
  • 如果您的组件需要性能调整(如果性能有问题,则):

一般方法,如何开发类似文本框的组件是为了使其无状态。组件直接呈现道具,并通知父组件有关更改,它不关心管理价值。

希望这会有所帮助

答案 2 :(得分:1)

请考虑pureComponent通过defualt实现shouldComponentUpdate里面的浅层等于用于上一个和下一个之间的比较

尝试以下代码:

class MyComponent extends PureComponent {...}