反応ルータv 6:アニメーション遷移


反応ルータv 5の上でアニメーションを通して移行DIYを作ることに感謝します.
さて、V 6で作ってみます.

では、始めましょう!


まず、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 /> ( v 5では<Switch /> ) は、ルートに一致するための現在のURLを使用しますが、我々はそれを場所を割り当てることによって行うことからそれを停止することができます.
<Routes location={displayLocation}>
我々は、現在の場所を維持するために状態を必要とする'アウト'アニメーション仕上げ、我々はデフォルトの値として現在の場所を割り当てることができます.UserLocationを使用して現在の場所を取得できます.
  ...
  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>
  );
}
ありがとう!