React中状态变化的动画

问题描述 投票:1回答:2

在我的React应用程序中,我有一个菜单,其中包含每个项目的子菜单。只要单击该项目,子菜单就会滑入。发生这种情况时,菜单标题也会更改。我想为标题更改设置动画,以便有一个平滑的淡入淡出效果。考虑一下React组件的render方法内的以下代码片段:

render() {
   // other code
   return(
     <div className={`title ${this.state.subMenu.isOpen ? `open` : ''}`}>
        <div>{this.state.heading}</div> // this heading changes when the sub-menu opens/renders
     </div>
  )
}

CSS:

@keyframes fade {
    0%,100% { opacity: 1 }
    50% { opacity: 0 }
}

.title {
   background : black;
   color : white;
}

.title.open {
   animation: fade 500ms ease-in-out;
}

此方法的问题在于,在状态更改后重新渲染组件之后将应用open类,因此,动画在渲染新的标题之后开始。这样会产生闪烁效果。但是,我希望动画在状态更改开始后立即开始。我为此查看了react-transition-group,但似乎没有为这种情况提供所需的解决方案。在下面的代码中,CSSTransition要求从DOM上安装和卸载其子代。在此期间,仅DOM元素的值(标题)会更改。

<CSSTransition
    in={this.state.subMenu.isOpen}
    timeout={500}
    classNames="open">
    <div className={`title ${subMenu.isOpen ? `open` : ''}`}>
        <div>{this.state.heading}</div> // heading changes when the sub-menu opens
    </div>
</CSSTransition>

有没有办法达到预期的结果?

javascript reactjs
2个回答
0
投票

您可以使用getSnapshotBeforeUpdate,对其进行阅读here

但是,如果您不能使用它,则可以在任何状态更改后希望具有副作用的情况下使用componentDidUpdate


0
投票

我相信您指的是这样的闪烁

Edit new-star-q12lv

仅当状态属性(或道具)发生变化时才触发内部动画,因此动画仅在下一个渲染中开始。好吧,这与hooks的执行方式有关。默认情况下,它是这样的

  • React向组件询问给定状态的UI
  • 您的组件说:好的!这是jsx,也可以运行此效果
  • React更新DOM并等待浏览器绘制
  • 反应运行效果

但是为什么要等待浏览器绘制?这样,您就不会阻塞线程,因为大多数效果不会触发新的渲染。

但是您的情况很特殊,您需要在DOM更新之前执行给定的更新。

为此,React有一个名为useLayoutEffect的特殊钩子,它将在浏览器的绘画过程之前运行。对于您来说,这只是一个完美的用例

Edit vigorous-frog-s95o8

不再闪烁。

基于类的组件,因为componentDidUpdate的行为要在更新之后运行,我怕getSnapshotBeforeUpdate在这里无法为您提供帮助。如果您收到open作为道具,可以看看getDerivedStateFromProps

话虽如此。好吧...难道您不只是将初始不透明度定义为0并在动画之后添加className来保持opacity: 1吗?

© www.soinside.com 2019 - 2024. All rights reserved.