首页 > 解决方案 > React:如何动画移除 DOM 元素?

问题描述

我的 React 组件有一个横幅,我想在其中添加“关闭”功能。当前的实现如下所示:

function Home() {
  return(
    <Banner />
    <Main />
  );
}

function Banner() {
  const [hide, setHide] = React.useState(false);
  const handleClick = () => setHide(true);
  return !hide ? (
    <div>
      This is a banner.
      <button onClick={handleClick}>Dismiss</button>
    </div> : null;
}

然而,这个实现是相当突然的,我不能动画它。有没有更好的方法来避免元素跳跃以提供更好的 UI?

标签: javascriptcssreactjs

解决方案


我对 React 动画的首选是 react-transition-group 库。(当然还有其他选择)。 这是我的 Stackblitz 演示

它相当容易使用。您将想要动画的组件包装在CSSTransition组件中,添加一些配置属性,并在样式表中设置样式。一个小问题是 timeout 属性必须与样式表中的转换时间相同。有关更多信息,请参阅文档

这是演示中最相关的代码:

应用组件

export function App() {
  const [showBanner, setShowBanner] = useState(true);
  const hideBannerHandler = () => setShowBanner(false);
  const showBannerHandler = () => setShowBanner(true);

  return (
    <div>
      <button onClick={showBannerHandler}>show banner</button>
      <CSSTransition
        in={showBanner}
        timeout={{
          enter: 0,
          exit: 2000
        }}
        unmountOnExit
        classNames="my-node"
      >
        <Banner hideBannerHandler={hideBannerHandler} />
      </CSSTransition>
    </div>
  );
}

CSS(片段)


.my-node-exit {
  opacity: 1;
}

.my-node-exit-active {
  animation: foo 2s ease forwards;
  transform-origin: left;
}

@keyframes foo {
  from {
    opacity: 1;
    background: pink;
    transform: translate(0, 0);
    box-shadow: 0 0 2px 3px pink;
    color: red;
  }

  50% {
    transform: scale(2);
    background: coral;
    box-shadow: 0 0 2px 3px coral;
    color: limegreen;
  }

  to {
    opacity: 0;
    transform: scale(1);
    background: white;
    color: white;
  }
}

推荐阅读