admin管理员组

文章数量:1277377

I have a banner my React ponent, to which I want to add "dismiss" capability. The current implementation looks like:

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;
}

However, this implementation is rather abrupt and I can't animate it. Is there a better way to avoid jumping of the elements to provide a better UI?

I have a banner my React ponent, to which I want to add "dismiss" capability. The current implementation looks like:

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;
}

However, this implementation is rather abrupt and I can't animate it. Is there a better way to avoid jumping of the elements to provide a better UI?

Share Improve this question edited Sep 6, 2024 at 9:45 Mark Rotteveel 109k229 gold badges156 silver badges220 bronze badges asked Oct 14, 2020 at 8:56 acagastyaacagastya 3931 gold badge2 silver badges15 bronze badges 5
  • Instead of pletely removes it, why not hide it though css? – Hao Wu Commented Oct 14, 2020 at 9:01
  • @HaoWu The ponent is really not required after dismissal, so it has no use there. That is the hacky solution that I know of -- but I want to know what is the proper way of doing it. – acagastya Commented Oct 14, 2020 at 9:04
  • 1 First you have to animate the size or opacity and then simply remove it AFTER that animation. You can't animate the display property so shrinking it to zero size first and then removing it would be the eimplest method. – Paulie_D Commented Oct 14, 2020 at 9:44
  • Will there also have to be an animation when it is shown? – Richard Hunter Commented Oct 14, 2020 at 10:58
  • @RichardHunter No, it is not mandatory. – acagastya Commented Oct 14, 2020 at 16:45
Add a ment  | 

1 Answer 1

Reset to default 7

My preferred choice for React animations is the react-transition-group library. (There are of course other options). Here is my Stackblitz demo

It's fairly easy to use. You wrap the ponent you want to animate in the CSSTransition ponent, add some config properties, and set your styles in a style sheet. One slight gotcha is that the timeout property has to be the same value as the transition times in the stylesheets. See documentation for more information.

Here is the most relevant code from the demo:

App Component

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 (fragment)


.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;
  }
}

本文标签: javascriptHow to animate removal of a DOM elementStack Overflow