我正在构建一个有希望处理我的动画的应用程序。由于几次试验,我得到以下错误:
警告:无法在尚未安装的组件上调用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环境中如何看待此解决方案?更普遍的赞赏?
任何提示都会很棒,
谢谢
答案 0 :(得分:2)
通常来说,您做对了。在componentDidMount
中进行异步操作是安全的,因为该生命周期挂钩不会阻止渲染。唯一需要注意的是,它只能运行一次。
如果您需要对道具更改做出反应,则可以考虑使用componentDidUpdate
,它有相反的警告,仅在道具更改时运行,而不在初始渲染后运行。您也可以考虑使用getSnapshotBeforeUpdate,它会在最近渲染的输出提交到例如DOM。它使您的组件可以在DOM可能发生更改之前从DOM捕获一些信息(例如,滚动位置)。此生命周期返回的任何值都将作为参数传递给componentDidUpdate()。