ReactJS _ Promise-可以在componentDidMount()方法中初始化函数吗?

时间:2019-01-29 17:40:26

标签: javascript reactjs promise

我正在构建一个有希望处理我的动画的应用程序。由于几次试验,我得到以下错误:

  

警告:无法在尚未安装的组件上调用setState。这是一个   无操作,但这可能表明您的应用程序中存在错误。代替,   直接分配给this.state或定义状态= {};阶级财产   并在App组件中具有所需的状态。”

为解决此警告,我将Promise函数插入了componentDidMount()方法中,从而确保在按以下方式调用时已装入组件:

componentDidMount() {
   this.setExitAnimation=new Promise((resolve, reject)=>{  
        {code here...}
 }

我打算这样做:http://mverissimo.github.io/tweenslideshow,在我的沙箱中:如果您感兴趣:http://codesandbox.io/s/64l5xyp2mz-图像组件上有一个bugg,它跟随其他元素动画而不是触发其动画具体顺序。

关于我的诺言,这是我的reactJS代码段:

 // set animation name 
      // => then callback other functions with the animation name
 setAnimation=()=>{   
    // appreciate if enter or exit flow
    if(this.state.exitLoop){ 
      // if exit flow, trigger the setting for exiting's animation
      this.setExitAnimation.then((anim)=> {  
        // then callback function to trigger the relevant animation °for image or text°
        this.state.elementType === "text"?
          this.triggerTextAnimation(anim)  
          :
          this.triggerImageAnimation(anim) 
      })
    }else{ 
      // if enter flow, trigger the setting for entering's animation
      this.setEnterAnimation.then((anim)=>{ 
        // then callback function to trigger the relevant animation °for image or text° 
        this.state.elementType === "text"?
          this.triggerTextAnimation(anim)  
          :
          this.triggerImageAnimation(anim) 
      });
    }  
  }

// set animation' name in case of enteringOnPage's flow
setEnterAnimation=new Promise((resolve, reject)=>{  
  console.log("in setEnterAnimation")
  // appreciate the element type to select which update todo on state
     // also appreciate the specific animation sequence to set on the state
  if(this.state.elementType ==="text"){
    if(this.state.currentView % 2 === 0){ 
      this.setState({textAnimation:enterDownAnimation});
      resolve(enterDownAnimation);
    }else{
        this.setState({textAnimation:enterUpAnimation}) 
    }    
  }else{ 
    switch(this.state.currentView){ 
      case 0: 
        this.setState({imageAnimation:enterSideAnimation});
        break;
      case 1: 
        this.setState({imageAnimation:enterUpAnimation});
        break;
      case 2: 
        this.setState({imageAnimation:enterDownAnimation});
        break;
      case 3: 
        this.setState({imageAnimation:enterSideAnimation});
        break;
      case 4: 
        this.setState({imageAnimation:enterUpAnimation});
        break;
      default:
        console.log("no animation found")
        break; // test return
    }
  }
})

// set animation' name in case of exitingPage's flow
setExitAnimation=new Promise((resolve, reject)=>{  
   // appreciate the element type to select which update todo on state
      // also appreciate the specific animation sequence to set on the state
  if(this.state.elementType ==="text"){
    if(this.state.currentView % 2 === 0){ 
        this.setState({textAnimation:exitDownAnimation});
        resolve(exitDownAnimation);
    }else{
        this.setState({textAnimation:exitUpAnimation});
        resolve(exitDownAnimation);
    }
  }else{ 
    console.log("currentView: ", this.state.currentView)
    switch(this.state.currentView){ 
      case 0: 
        this.setState({imageAnimation:exitSideAnimation});
        resolve(exitSideAnimation)
        break;
      case 1: 
        this.setState({imageAnimation:exitUpAnimation});
        resolve(exitUpAnimation)
        break;
      case 2: 
        this.setState({imageAnimation:exitDownAnimation});
        resolve(exitDownAnimation)
        break;
      case 3: 
        this.setState({imageAnimation:exitSideAnimation});
        resolve(exitSideAnimation)
        break;
      case 4: 
        this.setState({imageAnimation:exitUpAnimation});
        resolve(exitUpAnimation)
        break;
      default:
        console.log("no animation found")
        break; // test return
    }
  }
}) 

您在Promise环境中如何看待此解决方案?更普遍的赞赏?

任何提示都会很棒,

谢谢

1 个答案:

答案 0 :(得分:2)

通常来说,您做对了。在componentDidMount中进行异步操作是安全的,因为该生命周期挂钩不会阻止渲染。唯一需要注意的是,它只能运行一次。

如果您需要对道具更改做出反应,则可以考虑使用componentDidUpdate,它有相反的警告,仅在道具更改时运行,而不在初始渲染后运行。您也可以考虑使用getSnapshotBeforeUpdate,它会在最近渲染的输出提交到例如DOM。它使您的组件可以在DOM可能发生更改之前从DOM捕获一些信息(例如,滚动位置)。此生命周期返回的任何值都将作为参数传递给componentDidUpdate()。