Javascript 如何在 React 中不使用 componentWillReceiveProps 处理道具更改

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/43372359/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 01:52:56  来源:igfitidea点击:

How to handle props changes without using componentWillReceiveProps in React

javascriptreactjsreduxstate

提问by Tugrul

I've been working on a project which is coded with React. I have a component set that I implemented many components for my own requirements. Many of these act like a composite component. For example, TextBoxcomponent which has its own label, own error message mechanism and own input filteretc. Moreover, you know, components have props to manage sth.

我一直在研究一个用 React 编码的项目。我有一个组件集,我根据自己的要求实现了许多组件。其中许多就像一个复合组件。例如,TextBox组件有自己的标签、自己的错误消息机制和自己的输入过滤器等。此外,您知道,组件有管理某些东西的道具。

Everytime to update my component view (render), I use componentWillReceivePropsand I compare the props changes.

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

But everytime implementing the componentWillReceivePropsmethod is so repulsive.

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

Is there any way to pass props from top to down without using componentWillReceiveProps. I don't want to compare props changes manually. Is there any way to do it automatically.

有没有什么方法可以不使用componentWillReceiveProps. 我不想手动比较道具的变化。有什么办法可以自动完成。

When I change the props in parent, I'd like to update all views just changing the some prop values from top to down.

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

I'm not an react expert and performance is not my first purpose also!

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

One more thing that the answer is not use Redux!

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

I'm waiting your creative approaches and helpful ideas.

我在等待您的创造性方法和有用的想法。

回答by Benjamin Robinson

Without seeing the code for the particular thing you're working on, I may be missing something about what you're doing...

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

As others have commented, React will re-render your component if new props are provided, regardless of whether or not you implement componentWillReceiveProps-- the only reason to implement it is to do some kind of specific comparison or set a state based on new prop values.

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

From the React docs (emphasis mine):

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

componentWillReceiveProps() is invoked before a mounted component receives new props. If you need to update the state in response to prop changes (for example, to reset it), you may compare this.props and nextProps and perform state transitions using this.setState() in this method.

Note that React may call this method even if the props have not changed, so make sure to compare the current and next values if you only want to handle changes. This may occur when the parent component causes your component to re-render.

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

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

In other words, if you have a component like:

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

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

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

That internally passes prop changes on to a couple of child components like:

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

class TextBox extends React.Component {

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

}

Then each time new props are passed to <TextBox>, <Title>and <Body>will also get re-rendered with their new textprops, and there's no reason to use componentWillReceivePropsif you're just looking to update with prop changes. React will automatically see the changes and re-render. And React handles diffing and should fairly efficiently re-render only things that have changed.

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

However, if you have a separate state value that needs to be set in response to props, for example, if you wanted to show a "changed" state (or whatever) on the component if the new props are different, then you could implement componentWillReceiveProps, like:

但是,如果您有一个单独的状态值需要设置以响应道具,例如,如果您想在新道具不同的情况下在组件上显示“已更改”状态(或其他),那么您可以实现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>
    );
  }

}

If you're trying to prevent re-render in cases where it's unnecessary for performance, do as Andrey suggests and use shouldComponentUpdate: https://facebook.github.io/react/docs/react-component.html#shouldcomponentupdate

如果您试图在不需要性能的情况下阻止重新渲染,请按照 Andrey 建议并使用shouldComponentUpdatehttps: //facebook.github.io/react/docs/react-component.html#shouldcomponentupdate

TLDR; unless you're setting component state from props, there's likely no need to run new props through componentWillReceiveProps

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

UPDATE Feb 2018:in a future release, React will be deprecating componentWillReceivePropsin favor of the new getDerivedStateFromProps, more info here: https://medium.com/@baphemot/whats-new-in-react-16-3-d2c9b7b6193b

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

回答by Andrii Muzalevskyi

There are few suggestions:

有几个建议:

  • Don't copy props into state in componentWillReceiveProps- just render directly from this.props
  • If your component need performance tweak (and onlyif there is problem with performance):
  • 不要将道具复制到状态中componentWillReceiveProps- 直接从this.props
  • 如果您的组件需要性能调整(并且当存在性能问题时):

The general approach, how to develop text-box-like components is to keep it stateless.Component renders props directly, and notifies parent component about changes, it don't cares about managing value.

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

Hope this will help

希望这会有所帮助

回答by Deng Zhebin

Please consider pureComponentwhich by defualt implements the shouldComponentUpdateinside which shallow equals is used for comparison between previous and next

请考虑pureComponent哪个默认实现了shouldComponentUpdate浅等于的内部用于上一个和下一个之间的比较

try following codes:

尝试以下代码:

class MyComponent extends PureComponent {...}

class MyComponent extends PureComponent {...}