最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - How to prevent animation on initial render? - Stack Overflow

programmeradmin6浏览0评论

I have a ponent that has dynamic class names based on the state of the ponent. The initial state of the menu ponent is false so an exit animation triggers when I load the site. I'm trying to not play the exit animation on initial render, I'm trying to trigger the animation only when the user clicks away from the menu.

@keyframes menuEnter {
    from {
        transform: translateY(-100vh);
    }
    to {
        transform: translateY(0);
    }
}

@keyframes menuExit {
    from {
        transform: translateY(0);
    } 
    to {
        transform: translateY(-100vh);
    }
}
const [showMenu, setShowMenu] = useState(false)
<div className={`menuContainer ${showMenu ? `menuEnter` : 'menuExit'}`} id='menu'>

I'm trying to bail out of the exit animation because it doesn't make sense to play the exit animation on initial render.

The state changes onClick, when state is true onClick sets it to false and when state is false the onClick sets it to true.

I have a ponent that has dynamic class names based on the state of the ponent. The initial state of the menu ponent is false so an exit animation triggers when I load the site. I'm trying to not play the exit animation on initial render, I'm trying to trigger the animation only when the user clicks away from the menu.

@keyframes menuEnter {
    from {
        transform: translateY(-100vh);
    }
    to {
        transform: translateY(0);
    }
}

@keyframes menuExit {
    from {
        transform: translateY(0);
    } 
    to {
        transform: translateY(-100vh);
    }
}
const [showMenu, setShowMenu] = useState(false)
<div className={`menuContainer ${showMenu ? `menuEnter` : 'menuExit'}`} id='menu'>

I'm trying to bail out of the exit animation because it doesn't make sense to play the exit animation on initial render.

The state changes onClick, when state is true onClick sets it to false and when state is false the onClick sets it to true.

Share Improve this question edited Aug 29, 2020 at 17:39 Jonatan Tibarovsky asked Aug 29, 2020 at 17:18 Jonatan TibarovskyJonatan Tibarovsky 932 silver badges8 bronze badges 2
  • you need to rethink the conditions. You should add menuExit only if your menu is opened. And also add the classes on an event triggered by your menu trigger ( hover, click whatever ) – Mihai T Commented Aug 29, 2020 at 17:32
  • Edited my question. What would be another way dealing with the conditions? – Jonatan Tibarovsky Commented Aug 29, 2020 at 17:40
Add a ment  | 

3 Answers 3

Reset to default 5

The javascript is okay, it's the CSS that needs fixing. Instead of using animations, just use transitions so the menu doesn't go from open to close on render.

Try the following:

Add a transition to your menu id:

#menu {
    transition: 0.3s ease-out;
}

Then change this value by switching between a menu open and close class:

 .menuEnter {
    transform: translateY(0);
}

 .menuExit {
    transform: translateY(-100vh);
}

That way, when the ponent renders, the menu doesn't go from one animation state to another, it remains closed.

PS: Consider using 3d transforms for performance reasons.

You can achieve this by defaulting showMenu to undefined,

const [showMenu, setShowMenu] = useState(undefined)
<div className={`menuContainer ${showMenu ? `menuEnter` : showMenu === undefined ? '' : 'menuExit'}`} id='menu'>

I had same issue and I ended up adding transition class to onClick before menu gets opened or closed:

const { useState,useEffect } = React

const Example = () => {
  const [showMenu, setShowMenu] = useState(false)
  const [menuMounted, setMenuMounted] = useState(false)
  const mountedClass = menuMounted ? 'mounted' : ''
  const showMenuClass = showMenu ? 'menuOpen' : 'menuClosed'
  
  useEffect(() => {
    // imitate redux state change
    setTimeout(() => setShowMenu(true), 2000)
  }, [])
  
  return (
    <>
      <button onClick={() => {
        setMenuMounted(true)
        setShowMenu(!showMenu)
      }}>Toggle</button>
      <div className={`menuContainer ${showMenuClass} ${mountedClass}`}>
        1<br/>1<br/>1<br/>1<br/>1<br/>1<br/>
      </div>
    </>
  )
}

ReactDOM.createRoot(document.getElementById("root")).render(
  <Example />
)
.menuContainer {
  overflow: hidden;
}

.mounted {
  transition:
    height 0.3s ease-in-out,
    box-shadow 0.1s linear;
}

.menuClosed {
  height: 0;
}

.menuOpen {
  height: 110px;
}
<script src="https://cdnjs.cloudflare./ajax/libs/react/18.3.1/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare./ajax/libs/react-dom/18.3.1/umd/react-dom.production.min.js"></script>
<div id="root"></div>

发布评论

评论列表(0)

  1. 暂无评论