React-Router v6: 애니메이션 전환 DIY

React-router v5에서 애니메이션을 통해 전환 DIY를 만들어 주셔서 감사합니다.

이제 v6로 만들어 보도록 하겠습니다.

자, 시작합시다!



먼저 App 구성 요소를 생성해 보겠습니다.

export default function App() {
  return (
    <BrowserRouter>
      <div className={`App`}>
        <nav>
          <Link to="/">Home</Link>
          <Link to="/other">Other</Link>
        </nav>
        <Content />
      </div>
    </BrowserRouter>
  );
}


그런 다음 콘텐츠 구성 요소는 다음을 수행합니다.

function Content() {
    return (
    <div>
      <Routes>
        <Route path="/" element={<section>Home</section>} />
        <Route path="/other" element={<section>Other</section>} />
      </Routes>
    </div>
  );
}



이제 경로 전환을 중지해야 합니다. 기본적으로 <Routes /> (v5에서 <Switch /> )는 경로를 일치시키기 위해 현재 URL을 사용하지만 위치를 할당하여 이를 중지할 수 있습니다.

<Routes location={displayLocation}>


'Out' 애니메이션이 끝나기 전에 현재 위치를 유지하기 위한 상태가 필요하며 현재 위치를 기본값으로 지정할 수 있습니다. useLocation을 사용하여 현재 위치를 가져올 수 있습니다.

  ...
  const location = useLocation();
  const [displayLocation, setDisplayLocation] = useState(location);
  ...
  <Switch location={displayLocation}>


이제 링크를 클릭하면 URL이 변경되더라도 콘텐츠는 동일하게 유지된다는 것을 알 수 있습니다.

다음으로 전환 단계를 제어하기 위한 상태를 추가해야 합니다.

const [transitionStage, setTransistionStage] = useState("fadeIn");


그런 다음 useEffect를 사용하여 위치가 변경되었는지 확인하고 'fadeOut'을 시작할 수 있습니다.

  useEffect(() => {
    if (location !== displayLocation) setTransistionStage("fadeOut");
  }, [location, displayLocation]);


마지막으로 애니메이션이 끝나면 스테이지와 위치를 업데이트하는 방법이 필요합니다. 이를 위해 onAnimationEnd 이벤트를 사용할 수 있습니다.

function Content() {
  ...
  return (
    <div
      className={`${transitionStage}`}
      onAnimationEnd={() => {
        if (transitionStage === "fadeOut") {
          setTransistionStage("fadeIn");
          setDisplayLocation(location);
        }
      }}
    >
      ...
    </div>
  );
}


완료하기 전에 다음을 CSS에 추가해야 합니다.

.fadeIn {
  animation: 0.5s fadeIn forwards;
}

.fadeOut {
  animation: 0.5s fadeOut forwards;
}

@keyframes fadeIn {
  from {
    opacity: 0;
    transform: translate(-20px, 0);
  }
  to {
    opacity: 1;
    transform: translate(0px, 0px);
  }
}

@keyframes fadeOut {
  from {
    opacity: 1;
    transform: translate(0px, 0px);
  }
  to {
    transform: translate(-20px, 0);
    opacity: 0;
  }
}


그리고 데모와 완성된 코드는 다음과 같습니다.



import { useState, useEffect } from "react";
import {
  BrowserRouter,
  Link,
  useLocation,
  Route,
  Routes
} from "react-router-dom";
import "./styles.css";

export default function App() {
  return (
    <BrowserRouter>
      <div className={`App`}>
        <nav>
          <Link to="/">Home</Link>
          <Link to="/other">Other</Link>
        </nav>
        <Content />
      </div>
    </BrowserRouter>
  );
}

function Content() {
  const location = useLocation();

  const [displayLocation, setDisplayLocation] = useState(location);
  const [transitionStage, setTransistionStage] = useState("fadeIn");

  useEffect(() => {
    if (location !== displayLocation) setTransistionStage("fadeOut");
  }, [location, displayLocation]);

  return (
    <div
      className={`${transitionStage}`}
      onAnimationEnd={() => {
        if (transitionStage === "fadeOut") {
          setTransistionStage("fadeIn");
          setDisplayLocation(location);
        }
      }}
    >
      <Routes location={displayLocation}>
        <Route path="/" element={<section>Home</section>} />
        <Route path="/other" element={<section>Other</section>} />
      </Routes>
    </div>
  );
}


고맙습니다 !

좋은 웹페이지 즐겨찾기