Home > Blockchain >  Make children elements render only after parent element transition is over?
Make children elements render only after parent element transition is over?

Time:11-25

I have a nav bar that when expanded transitions to use 50% of the screen, inside of this expanded nav element, is a search field component. The problem I'm facing is that the search field is appearing before the nav bar finishes expanding(which I know makes sense). I just can't figure how to fix that. Thanks in advance! This is the relevant code:

JSX:

const NavMobile = () => {
  const [isExpanded, setIsExpanded] = useState(false);

  const expandNav = () => {
    document.getElementById("nav")?.classList.add("expanded");
    setIsExpanded(true);
  };

  const closeNav = () => {
    document.getElementById("nav")?.classList.remove("expanded");
    setIsExpanded(false);
  };

  return (
    <div id="nav" className="navWrapper">
      <nav className="container">
        <button
          className="navButton"
          style={{ display: isExpanded ? "none" : undefined }}
          onClick={expandNav}
        >
          <i className="fa fa-search"></i> Search a service ...
        </button>
        {isExpanded ? (
          <div className="expandedContainer">
            <ServiceSearchFields />
          </div>
        ) : null}
      </nav>
    </div>
  );
};

SCSS:

.navWrapper {
    transition: 1000ms;
    box-shadow: 2px 4px 5px 0px rgba(0, 0, 0, 0.53);
    height: 70px;
    background-color: var(--mainColor);
    display: flex;
    margin: 0;
}

.expanded {
    height: 35vh !important;
}

.expandedContainer {
    height: 100%;
    display: flex;
    flex-direction: column;
    justify-content: flex-start;
    align-items: center;
    gap: 15px;
  }

CodePudding user response:

It could be a good idea to use the 'transitionend' event listener attached to your wrapper. Sample: https://stackblitz.com/edit/react-5k1ssu Please check the example below:

import React, { useState, useRef, useEffect } from 'react';
import './style.css';

const NavMobile = () => {
  const [isExpanded, setIsExpanded] = useState(false);
  const [isSearchVisible, setIsSearchVisible] = useState(false);
  const wrapper = useRef(null);

  const expandNav = () => {
    document.getElementById('nav')?.classList.add('expanded');
    setIsExpanded(true);
  };

  const closeNav = () => {
    document.getElementById('nav')?.classList.remove('expanded');
    setIsExpanded(false);
  };

  const showSearch = () => {
    setIsSearchVisible(true);
  };

  useEffect(() => {
    if (!wrapper.current) return;

    wrapper.current.addEventListener('transitionend', showSearch);
    console.log(wrapper.current);
    return () => {
      wrapper.current.removeEventListener('transitionend', showSearch);
    };
  }, []);

  return (
    <div id="nav" ref={wrapper} className="navWrapper">
      <nav className="container">
        <button
          className="navButton"
          style={{ display: isExpanded ? 'none' : undefined }}
          onClick={expandNav}
        >
          <i className="fa fa-search"></i> Search a service ...
        </button>
        {isExpanded ? (
          <div className="expandedContainer">
            {isSearchVisible && <div>Search</div>}
          </div>
        ) : null}
      </nav>
    </div>
  );
};

export default function App() {
  return (
    <div>
      <NavMobile />
    </div>
  );
}
.navWrapper {
  transition: 1000ms;
  box-shadow: 2px 4px 5px 0px rgba(0, 0, 0, 0.53);
  height: 70px;
  background-color: var(--mainColor);
  display: flex;
  margin: 0;
}

.expanded {
  height: 35vh !important;
}

.expandedContainer {
  height: 100%;
  display: flex;
  flex-direction: column;
  justify-content: flex-start;
  align-items: center;
  gap: 15px;
}
<div id="root"></div>
<iframe name="sif1" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>

  • Related