代码之家  ›  专栏  ›  技术社区  ›  Webwoman

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

  •  1
  • Webwoman  · 技术社区  · 5 年前

    我正在构建一个应用程序,其中包含一些处理我的动画的承诺。由于很少试验,我得到以下错误:

    警告:无法对尚未安装的组件调用setState。这是一个 没有op,但它可能指示应用程序中存在错误。相反, 直接分配给this.state或定义state={};类属性 应用程序组件中的所需状态。

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

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

    我正努力做到这一点: http://mverissimo.github.io/tweenslideshow ,这里是我的沙盒:如果你感兴趣: http://codesandbox.io/s/64l5xyp2mz -图像组件上有一个错误,该错误跟随其他元素动画而不是触发其特定序列。

    这里是我关于我的承诺的反应片段:

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

    在承诺的情况下,你认为这个解决方案怎么样?更普遍的欣赏?

    任何暗示都很好,

    谢谢

    1 回复  |  直到 5 年前
        1
  •  2
  •   Dima Vishnyakov    5 年前

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

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