子组件未通过更改道具进行更新

时间:2019-12-08 23:17:26

标签: reactjs react-native react-native-ios

我正在尝试使用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正在这样接收它们(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对象时(状态更改时它已经更改),它应该作为新的脉冲组件道具使用,并且应该使用它们来更新自身。但是它没有这样做。

整个脉冲分量在这里: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()

4 个答案:

答案 0 :(得分:1)

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

答案 1 :(得分:0)

您快到了!

尽管有些逻辑混为一谈。这里的关键是,您需要保持数据在一个方向上流动。

在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 />

答案 2 :(得分:0)

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

在父母中,您将道具传递给孩子使用的道具,对于孩子来说,它认为它是固定的。因此它没有收到并更新。这是React虚拟末日更新机制。

因此在父级中,更改use 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} />


答案 3 :(得分:0)

感谢@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
      }



  }