【问题标题】:Animations not working when entering (Tailwind, TransitionGroup, Typescript)进入时动画不起作用(Tailwind、TransitionGroup、Typescript)
【发布时间】:2020-09-29 09:09:30
【问题描述】:

我创建了一个包装器组件以通过字符串提供类名列表以支持 Tailwind 实用程序转换。这旨在嵌套在 TransitionGroup 组件中,以支持多个项目的动画,例如列表。

我可以很好地制作动画,但输入不起作用。你能帮我找出这段代码中的错误吗?

反应 16.13.1 反应过渡组 4.4.1

沙盒:https://codesandbox.io/s/delicate-feather-ymozq

(登录那里查看 div 引用,以防类没有被应用,但它们似乎工作正常)

import React, { ReactNode } from "react";
import { Transition as ReactTransition } from "react-transition-group";

interface TransitionProps {
  in?: boolean;
  timeout: number;
  enter?: string;
  enterFrom?: string;
  enterTo?: string;
  leave?: string;
  leaveFrom?: string;
  leaveTo?: string;
  children: ReactNode;
}

export function CSSTransition(props: TransitionProps) {
  const { enter, enterFrom, enterTo, leave, leaveFrom, leaveTo } = props;
  const nodeRef = React.useRef<HTMLDivElement>(null);

  const enterClasses = splitClasses(enter);
  const enterFromClasses = splitClasses(enterFrom);
  const enterToClasses = splitClasses(enterTo);
  const leaveClasses = splitClasses(leave);
  const leaveFromClasses = splitClasses(leaveFrom);
  const leaveToClasses = splitClasses(leaveTo);

  function splitClasses(string: string | undefined): string[] {
    if (string) return string.split(" ").filter((s) => s.length);
    return [];
  }

  function addClasses(classes: string[]) {
    nodeRef.current?.classList.add(...classes);
  }

  function removeClasses(classes: string[]) {
    nodeRef.current?.classList.remove(...classes);
  }

  return (
    <ReactTransition
      in={props.in}
      nodeRef={nodeRef}
      timeout={props.timeout}
      unmountOnExit
      onEnter={() => {
        console.log("onEnter", nodeRef);
        addClasses([...enterClasses, ...enterFromClasses]);
      }}
      onEntering={() => {
        console.log("onEntering", nodeRef);
        removeClasses(enterFromClasses);
        addClasses(enterToClasses);
      }}
      onEntered={() => {
        console.log("onEntered", nodeRef);
        removeClasses([...enterToClasses, ...enterClasses]);
      }}
      onExit={() => {
        console.log("onExit", nodeRef);
        addClasses([...leaveClasses, ...leaveFromClasses]);
      }}
      onExiting={() => {
        console.log("onExiting", nodeRef);
        removeClasses(leaveFromClasses);
        addClasses(leaveToClasses);
      }}
      onExited={() => {
        console.log("onExited", nodeRef);
        removeClasses([...leaveToClasses, ...leaveClasses]);
      }}
    >
      <div ref={nodeRef}>{props.children}</div>
    </ReactTransition>
  );
}

【问题讨论】:

标签: javascript reactjs typescript tailwind-css react-transition-group


【解决方案1】:

解决方案:

CSSTransition.tsx,更改

import { Transition as ReactTransition } from "react-transition-group";

import { CSSTransition as ReactTransition } from "react-transition-group";

解释:

Tailwind 类名依赖于 CSS 动画。

Transition 不是为处理 CSS 动画而设计的,因为 onEnteronEntering 方法被调用得如此之快,以至于它们之间不会发生 DOM 重绘(动画的一帧)。因此,您为enterTo 设置的所有类都会立即应用,而没有任何机会过渡到它们。

另一方面,CSS Transition 在创建元素时添加一个-enter 类,然后在下一个刻度/帧上添加一个-enter-active 。最后,在超时之后,它会删除除了添加-done 类之外的所有类。

-enter-enter-active 类之间的转换是允许 CSS 转换发生的关键。在那些允许库强制重绘的类之间添加一个刻度/帧。此重绘会强制 onEntering 类按预期转换为 onEntered 类。

换句话说,Transition 立即切换到enterTo 状态,而CSSTransition 在类切换之间提供一帧,这是允许动画发生所需的。

DOM 通常以每秒最多 60 帧的速度进行动画/更改(取决于实现/最终用户屏幕刷新率),每帧留出 16 毫秒;它不关心这 16 毫秒之间发生了什么。如果类更改后的最终状态是您的 enterTo 状态而不是您的 enterFrom 状态,它将忽略 enterFrom 状态,因此永远不会向您显示 Tailwind 动画。

来源:

【讨论】:

  • 当然,就是这么简单。当然!太感谢了。这让我难过了好几天,但在这个过程中,我确实学到了很多关于 react-transition-group 如何工作的知识。它现在就像一个魅力。
猜你喜欢
  • 2022-11-04
  • 2021-12-21
  • 2021-09-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多