子组件不会通过更改道具来更新

Child component is not updating by changing props

我正在尝试使用 react-native-pulse,但在更新它时遇到了一些困难。我像这样在父级上使用组件:

 <Pulse  color={this.pulseOptions.pulseColor} numPulses={this.pulseOptions.numPulses} diameter={this.pulseOptions.diameter} speed={this.pulseOptions.speed} duration={this.pulseOptions.pulseDuration} />

现在,当状态改变时 pulseOptions 对象也在改变(有一个函数可以做到这一点),没问题,直到这里一切正常。问题是;它将新道具传输到 Pulse 组件,但 Pulse 组件不想接收它们并更新。

  state = {


    latitude: null,
    longitude: null,
    accuracy: null,

  }

  pulseOptions = {


    numPulses: 1,
    diameter:200,
    speed:5,
    pulseDuration:1000,
    pulseColor: '#8e44ad',

}

Pulse 正在像这样接收它们(脉冲分量):

constructor(props){
    super(props);

    this.state = {
        color: this.props.color,
        duration: this.props.duration,
        image: this.props.image,
        maxDiameter: this.props.diameter,
        numPulses: this.props.numPulses,
        pulses: [],
        pulseStyle: this.props.pulseStyle,
        speed: this.props.speed,
        started: false,
        style: this.props.style
    };


}

所以基本上我想要的是,当父组件中的 pulseOptions 对象发生更改时(它已经在状态更改时发生更改)它应该作为 pulse 组件的新道具,并且它应该使用它们更新自身。但是它没有这样做。

整个脉冲分量在这里:https://github.com/sahlhoff/react-native-pulse/blob/master/pulse.js

感谢您的帮助

编辑;当状态改变时:

  changePulseProps = () => {


                                                                      //Pulse Styling
                                                                      if (this.state.accuracy <= 20) {

                                                                        angryPulse = {
                                                                          numPulses: 4,
                                                                          diameter:500,
                                                                          speed:10,
                                                                          pulseDuration:1000,
                                                                          pulseColor: '#27ae60',

                                                                        }


                                                                        return  angryPulse

                                                              } 

并渲染:

            render () {


          this.pulseOptions = this.changePulseProps()

更新道具并不总是会更新组件的状态。状态在构造函数中设置,如果 React 认为没有必要重建组件,它只会被调用一次。 我建议你在你的子组件中实现一个 getDerivedStateFromProps 函数来管理更好的传入道具和新状态:https://en.reactjs.org/docs/react-component.html#static-getderivedstatefromprops

你快到了!

虽然有些逻辑有点混乱。这里的关键是你需要保持数据在一个方向上流动。

在 React 世界中,这意味着有状态值(可以随时间变化的值)将在更改时自动导致视图(用户看到的内容)更新。

您应该在组件状态中声明脉冲选项:

this.state = {

    latitude: null,
    longitude: null,
    accuracy: null,
    numPulses: 1,
    diameter:200,
    speed:5,
    pulseDuration:1000,
    pulseColor: '#8e44ad',
}

然后使用以下值调用组件:

 <Pulse  color={this.state.pulseColor} numPulses={this.state.numPulses} diameter={this.state.diameter} speed={this.state.speed} duration={this.state.pulseDuration} /> 

大概您需要添加一个 onChange 处理程序来更新状态

<Pulse onChange / onClick = {this.handleClick} ...rest of Component />

控制组件的数据有两种类型:props 和 state。道具由父级设置,并且它们在组件的整个生命周期中都是固定的。对于要改变的数据,我们必须使用状态。

在父级中,你将道具传递给子级使用道具,对于子级来说,它认为它是固定的。所以它没有收到和更新。它是 React 虚拟末日更新机制。

所以在父级中,更改使用 this.state 以将其传递给子级。

state = {
    latitude: null,
    longitude: null,
    accuracy: null,
    pulseOptions: {
    numPulses: 1,
    diameter:200,
    speed:5,
    pulseDuration:1000,
    pulseColor: '#8e44ad'
   }
 }


<Pulse  color={this.state.pulseOptions.pulseColor} numPulses={this.state.pulseOptions.numPulses} diameter={this.state.pulseOptions.diameter} speed={this.state.pulseOptions.speed} duration={this.state.pulseOptions.pulseDuration} />


感谢@borisbezzola getDerivedStateFromProps 完成了这项工作。刚刚将其添加到子组件:

    static getDerivedStateFromProps(props, state){

      return {
        ...state,
        color: props.color,
        duration: props.duration,
        image: props.image,
        maxDiameter: props.diameter,
        numPulses: props.numPulses,
        //pulses: [],
        pulseStyle: props.pulseStyle,
        speed: props.speed,
        //started: true,
        style: props.style
      }



  }