在状态更新后重新登记不起作用

时间:2017-07-19 08:41:31

标签: reactjs

我有一个父组件Rides,它通过props将数据发送到子组件。 这是Child组件:

class LazyLoader extends React.Component {
  constructor(props){
    super(props);
    this.state = {
      loaderState: this.props.loaderState
    }
  }
  componentWillReceiveProps(nextProps){
    console.log(`inside componentWillReceiveProps ${nextProps.loaderState}`);
    if(this.props != nextProps) {
      this.setState({
        loaderState: nextProps.loaderState
      }, () => {console.log(`Finished setState for ${nextProps.loaderState}`)});
    }
  }

  render(){
    console.log(`loaderState: ${this.state.loaderState}`);
    return (
      this.state.loaderState ? (
        <View style={[styles.container]}>
          <ActivityIndicator style={styles.spinner} animating={true} size={60} color='#fff'/>
        </View>) : (<View/>)
    )
  }
}

我的父组件(此处为Rides)的一部分,将state的更新数据发送给儿童(此处LazyLoaderprop:< / p>

export default class Rides extends React.Component {
  constructor(props){
    super(props);
    this.handleRidePress = this.handleRidePress.bind(this);
    this.navigateToRideDetails = this.navigateToRideDetails.bind(this);

    this.state = {
      flash: true
    };

  }

  handleRidePress(rideId){
    this.setState({
      flash: true
    }, () => {
      console.log(`Begining handleRidePress for rideId: ${rideId}`);
      if(doSomeTimeConsumingOperation){
        // Time consuming operation goes here
      }
      this.navigateToRideDetails({rideId: rideId, pingData:pingData.slice(), rideData: rideDetails});
    });
  }

  navigateToRideDetails(rideObj){

    this.setState({
      flash: false
    }, () => {console.log(`navigateToRideDetails setState cb`); this.props.navigation.navigate('RideLog', rideObj);});
  }

  render(){
    console.log(`flash: ${this.state.flash}`);
    return(
      <Gradient.FullGradient>
      <Reusables.LazyLoader loaderState={this.state.flash}/>
      <PRides rides={this.state.rideTiles} onDeletePress={this.deleteRide} navigation={this.props.navigation} onRideDetailPress={this.handleRidePress}/>
      </Gradient.FullGradient>
    )
  }
}

调用handleRidePress函数后,它会使用flash更新state setState(),但子组件不会重新呈现。我尝试在两个组件中使用shouldComponentUpdate()并默认返回true,但它不起作用。

2 个答案:

答案 0 :(得分:1)

我认为错误与你在这里比较两个对象的方式相同:

if(this.props != nextProps) {
    ....
}

这不是检查两个对象是否相同的正确方法,请检查值:

if(this.props.loaderState != nextProps.loaderState) {
    ....
}

检查此答案How to determine equality for two JavaScript objects?

检查此代码段:

let a = {b: true};

let b = {b: true};

console.log(a == b);    //false

答案 1 :(得分:0)

我修改navigateToRideDetails以独立执行setState,因为反应批处理事件处理程序和生命周期方法中发生的状态更新。因此,如果我们在函数处理程序中多次更新状态,React将在重新呈现之前等待事件处理完成。在我的情况下,flash中的state值在操作完成后重置。因此没有显示ActivityIndi​​cator。

这是修改后的navigateToRideDetails函数

navigateToRideDetails(rideObj){
    setTimeout(() => {
      this.setState({
        flash: false
      }, ()=>{
        this.props.navigation.navigate('RideLog', rideObj);
      });
    }, 0); 
  }

这解决了问题:)