[React] 特定のページで一定時間経過後に別ページに遷移させる

2021.07.23

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

こんにちは、CX事業本部 IoT事業部の若槻です。

今回は、Reactで実装したアプリケーションで特定のページで一定時間経過後に別ページに遷移させてみました。

〜ここから追記〜

2021/10/06

本エントリで紹介しているページ遷移の実装ですが、後日不適切な実装であることが分かったため、下記エントリで改めて適切な実装を紹介しています。

よって本エントリの内容は上記エントリと合わせて参考程度にご覧ください。

〜追記ここまで〜

環境

$ npm list --depth=0
...
├── @material-ui/core@4.12.2
├── react@17.0.2
├── typescript@4.2.4
...

コード

ページ構成は遷移元のThankYouPageと、遷移先のStartPageから成ります。

遷移元ページ

遷移元のThankYouPageページです。パスは/thankyouです。

components/pages/ThankYouPage.tsx

import React from "react";
import { makeStyles } from "@material-ui/core/styles";
import Typography from "@material-ui/core/Typography";

const useStyles = makeStyles((theme) => ({
  typography: {
    marginTop: theme.spacing(30),
    marginBottom: theme.spacing(30),
  },
}));

if (window.location.pathname === "/thankyou") {
  setTimeout(() => {
    window.location.href = "/start";
  }, 3 * 1000);
}

const ThankYouPage: React.FC = () => {
  const classes = useStyles();

  return (
    <Typography variant="h2" align="center" className={classes.typography}>
      <div>{"お疲れさまでした。"}</div>
      <div>{"3秒後にスタートページに戻ります。"}</div>
    </Typography>
  );
};

export default ThankYouPage;

setTimeout()で3秒後にwindow.location.hrefを実行して/startパスに遷移するようにしています。またその実行条件にwindow.location.pathname === "/thankyou"とすることにより、他のページでは遷移が発生しないようにしています。(ReactはSingle Page Applicationなので、この条件付をしなければ全てのページでsetTimeout()が実行されてしまいます。)

遷移先ページ、ルーティング

遷移先のStartPageページです。パスは/startです。

components/pages/StartPage.tsx

import React from "react";
import { makeStyles } from "@material-ui/core/styles";
import Button from "@material-ui/core/Button";
import Typography from "@material-ui/core/Typography";

const useStyles = makeStyles((theme) => ({
  typography: {
    marginTop: theme.spacing(20),
    marginBottom: theme.spacing(10),
  },
  button: {
    marginTop: "auto",
    marginBottom: theme.spacing(5),
    width: "250px",
    height: "200px",
    fontSize: "30px",
  },
}));

const StartPage: React.FC = () => {
  const classes = useStyles();

  return (
    <div>
      <Typography variant="h2" align="center" className={classes.typography}>
        <div>{"アンケートを開始します。"}</div>
      </Typography>
      <div
        style={{
          display: "flex",
          justifyContent: "center",
        }}
      >
        <Button
          variant="contained"
          color="primary"
          className={classes.button}
          onClick={() => {
            window.location.href = "/thankyou";
          }}
        >
          {"開始"}
        </Button>
      </div>
    </div>
  );
};

export default StartPage;

各ページのルーティングです。

App.tsx

import { BrowserRouter as Router, Route, Switch } from "react-router-dom";
import "./App.css";

import StartPage from "./components/pages/StartPage";
import ThankYouPage from "./components/pages/ThankYouPage";

const App: React.FC = () => {
  return (
    <Router>
      <Switch>
        <Route path="/" component={StartPage} exact />
        <Route path="/start" component={StartPage} exact />
        <Route path="/thankyou" component={ThankYouPage} exact />
      </Switch>
    </Router>
  );
};

export default App;

動作

アプリにアクセスすると既定で下記の/startページとなります。[開始]ボタンをクリックします。

すると/thankyouページが開きます。ここで3秒経過すると上記の/startに遷移して戻ります。

おわりに

Reactで実装したアプリケーションで特定のページで一定時間経過後に別ページに遷移させてみました。

Reactアプリで時間経過による動作を実装したことがなかったため、当初はReact Hooksなどを使うものだと思っていましたが、案外あっさり実装できました。しかし「あと○秒後に戻ります」のをカウントダウンさせるなどの実装をするならHooksを使うことになりそうなので、それは次回以降にやってみます。

参考

以上