在开始使用React.js后,似乎道具是静态的(从父组件传入),而状态是基于事件变化的。然而,我注意到在文档中有一个componentWillReceiveProps的引用,其中特别包括这个例子:

componentWillReceiveProps: function(nextProps) {
  this.setState({
    likesIncreasing: nextProps.likeCount > this.props.likeCount
  });
}

这似乎意味着,基于nextProps与This .props的比较,组件的属性可以改变。我错过了什么?道具是如何变化的,或者我弄错了这个在哪里被调用?


当前回答

组件不能更新自己的道具,除非它们是数组或对象(让组件更新自己的道具,即使有可能也是反模式),但可以更新它的状态和其子组件的道具。

例如,仪表板在其状态中有一个速度字段,并将其传递给显示此速度的Gauge子程序。它的渲染方法只是返回<Gauge speed={this.state。速度}/ >。当仪表盘调用这个。setState({speed: this.state.speed + 1}),则Gauge将使用新的speed值重新呈现。

在此之前,将调用Gauge的componentWillReceiveProps,以便Gauge有机会将新值与旧值进行比较。

其他回答

钩子已经改变了很多,例如componentWillReceiveProps变成了useEffect+useRef(在另一个SO答案中显示),但是Props仍然是只读的,所以只有调用方法应该更新它。

道具

React组件应该使用props来存储可以存储的信息 已更改,但只能由不同的组件更改。

状态

React组件应该使用状态来存储信息 组件本身可以改变。

Valéry已经提供了一个很好的例子。

当一个组件的父组件以不同的属性再次呈现该组件时,道具可以改变。我认为这主要是一种优化,这样就不需要实例化新的组件了。

组件不能更新自己的道具,除非它们是数组或对象(让组件更新自己的道具,即使有可能也是反模式),但可以更新它的状态和其子组件的道具。

例如,仪表板在其状态中有一个速度字段,并将其传递给显示此速度的Gauge子程序。它的渲染方法只是返回<Gauge speed={this.state。速度}/ >。当仪表盘调用这个。setState({speed: this.state.speed + 1}),则Gauge将使用新的speed值重新呈现。

在此之前,将调用Gauge的componentWillReceiveProps,以便Gauge有机会将新值与旧值进行比较。

如果使用重组,则使用mapProps从传入的道具派生出新的道具

例子:

import { compose, mapProps } from 'recompose';

const SomeComponent = ({ url, onComplete }) => (
  {url ? (
    <View />
  ) : null}
)

export default compose(
  mapProps(({ url, storeUrl, history, ...props }) => ({
    ...props,
    onClose: () => {
      history.goBack();
    },
    url: url || storeUrl,
  })),
)(SomeComponent);