【问题标题】:ReactJS _ Promise - Is it okay to initialize function in the componentDidMount() methods?ReactJS _ Promise - 可以在 componentDidMount() 方法中初始化函数吗?
【发布时间】:2019-01-29 17:40:26
【问题描述】:

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

警告:无法在尚未安装的组件上调用 setState。这是一个 无操作,但它可能表明您的应用程序中存在错误。反而, 直接赋值给 this.state 或者定义一个 state = {};类属性 在 App 组件中具有所需的状态。”

为了解决这个警告,我在 componentDidMount() 方法中插入了我的 Promise 函数,从而确保组件在调用时已安装,如下所示:

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

我正在尝试这样做:http://mverissimo.github.io/tweenslideshow,这里是我的沙箱:如果您有兴趣:http://codesandbox.io/s/64l5xyp2mz - 图像组件上有一个错误,它跟随其他元素动画而不是触发其特定序列。

这里是关于我的承诺的 reactJS sn-p:

 // 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 上下文中的这个解决方案?更普遍的赞赏?

任何提示都会很棒,

谢谢

【问题讨论】:

  • 请分享你在promise里面的相关代码
  • 好的,我已经包含了promise的sn-p
  • 你为什么还要在这里使用 Promise?代码中似乎没有任何异步内容。
  • 感谢评论,我希望我的代码有时间获取新动画的名称,然后将其返回给我的函数以触发新的动画名称
  • @Bergi 你有什么具体的建议可以和我们分享吗?

标签: javascript reactjs promise


【解决方案1】:

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

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

【讨论】:

    猜你喜欢
    • 2021-12-08
    • 2016-05-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-08-14
    • 2017-10-22
    • 1970-01-01
    • 2019-03-12
    相关资源
    最近更新 更多