react-routerとRailsのroutesを組み合わせる
はじめに
Reactでのフロントエンド開発を最近また業務でやっている。
前回やった時は半年ほど前に2,3スプリント分の機能を実装しただけなので、正直忘れてしまった状態からのスタートだ。
今回はreact-routerとRailsのroutesの兼ね合いについてのメモとしてこの記事を書く。
例の如くサンプルコード内の命名は無配慮なものになっているので、その点お目溢しを願う。
環境
React / TypeScript / Rails
背景
ユーザ登録の際に、一つ目のページでemailを入力し、二つ目のページでpasswordを入力する機能を作りたい。
(この記事では各種ページコンポーネントの実装は割愛する。 気が向いたら追記するかも。)
そして 1ページ目は
'/users/new/'
2ページ目は
'/users/new/pass'
というようなroutingを実現したい。
実装(React側)
Root.tsxは下記のような実装をした。
import React, { memo } from "react"; import { BrowserRouter, Route, Switch } from "react-router-dom"; import { EmailPage } from "./EmailPage"; import { PasswordPage } from "./PasswordPage"; import styles from "./Root.modules.scss" import { RegistrationContainer } from "./useRegistration"; export default function Root() { return ( <BrowserRouter> <RegistrationContainer.provider> <Component /> </RegistrationContainer.provider> </BrowserRouter> ); } const Component = memo(function Component() { const { ROUTES } = RegistrationContainer.useContainer(); return ( <div className={styles.base}> <Switch> <Route path={ROUTES.pass}> <PasswordPage /> </Route> <Route> <EmailPage /> </Route> </Switch> </div> ); }
今回使うpass自体はRegistrationContainerの方でROUTESとして下記のように実装している。 (ちなみにこのcontainerはunstated-nextで生成している。)
const ROUTES = { password_pass: path.resolve(baseUrl, "./"), phone_number_pass: path.resolve(baseUrl, "./"), } as const
Root.tsx内で上記containerから呼び出したROUTESのpassをRoute pathに代入している。
実装(Rails側)
今回登場したパス、
1ページ目は
'/users/new/'
2ページ目は
'/users/new/pass'
であるが、2ページ目のパスに関してはRails側は感知できないので、 ユーザーが2ページ目を開いている時にページを再読み込すると、Rails側が理解できないリクエストが送られてしまう。
なので、Rails側のroutes.rbで
get '/users/new/pass', to: redirect('/users/new')
とredirectしてあげれば良い。
最後に
どなたかのためになれば甚だ幸いだ。 また間違いなどあれば、ご指摘いただけると嬉しい。