代码之家  ›  专栏  ›  技术社区  ›  Suresh Prajapati

状态更新后重新加载不工作

  •  0
  • Suresh Prajapati  · 技术社区  · 7 年前

    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/>)
        )
      }
    }
    

    和我父组件的一部分(此处 state 给孩子的(这里 LazyLoader prop :

    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 setState() 但子组件并没有获得重新渲染。我试过使用 shouldComponentUpdate() 在组件和返回中 true 默认情况下,但它不起作用。

    2 回复  |  直到 7 年前
        1
  •  1
  •   Jose Paredes    7 年前

    我认为错误在于你在这里比较两个物体的方式:

    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
        2
  •  0
  •   Suresh Prajapati    7 年前

    我修改了 navigateToRideDetails 执行 setState 在事件处理程序和生命周期方法中独立地进行状态更新。因此,如果我们在函数处理程序中多次更新状态,React将在重新呈现之前等待事件处理完成。就我而言 flash state 在操作完成后正在重置。因此未显示ActivityIndicator。

    此处已修改 作用

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

    这解决了问题:)