もふもふ技術部

IT技術系mofmofメディア

Rails7 に React + TypeScript を導入する

Rails7のアプリでJSのビルドツールはesbuildを使用します。
環境構築の方法はこちらを参照ください↓↓
www.mof-mof.co.jp

ReactとTypeScriptをインストールする

  1. 以下のコマンドで必要なパッケージをインストール

    yarn add typescript react react-dom react-router-dom @types/react @types/react-dom @types/react-router-dom
    
  2. package.json のビルドスクリプトの末尾に --loader:.js=jsx を追記
    例)

    "build:js": "esbuild app/javascript/*.* --bundle --sourcemap --outdir=app/assets/builds --loader:.js=jsx"
    

各種ファイルを作成する

  1. rails g controller front index でコントローラーを追加する
  2. config/routes を修正する
    1. get 'front/index' を削除
    2. 以下を追加

      root to: 'front#index'
      get '*path', to: 'front#index'
      
  3. app/views/top/index.html.erb を修正する

    <div id="root"></div>
    
  4. app/javascript/application.js に以下を追記する

    import React from 'react';
    import { createRoot } from 'react-dom/client';
    import { App } from './react/App';
    
    const container = document.getElementById('root');
    if (container) {
      const root = createRoot(container);
    
      document.addEventListener('DOMContentLoaded', () => {
        root.render(<App />);
      });
    }
    
  5. 以下のファイルを作成する
    1. app/javascript/react/App.tsx

      import React from 'react'
      import { BrowserRouter as Router } from 'react-router-dom'
      import { AppRoutes } from './AppRoutes'
      
      export const App: React.FC = () => {
        return (
          <Router>
            <AppRoutes />
          </Router>
        )
      }
      
    2. app/javascript/react/AppRoutes.tsx

      import React from 'react';
      import { Routes, Route } from 'react-router-dom';
      import { Top } from './pages/Top';
      
      export const AppRoutes = () => {
        return (
          <>
            <Routes>
              <Route path="/" element={<Top />} />
            </Routes>
          </>
        )
      };
      
    3. app/javascript/react/pages/Top.tsx

      import React from 'react';
      
      export const Top = () => {
        return (
          <>
            <div>トップページ</div>
          </>
        );
      };
      

これで、http://localhost:3000/ にアクセスすると、「トップページ」と表示されると思います。

他のページを作成する

他のページを作成する場合は、新しいファイルとルーティングを追加するだけでできます。

  1. app/javascript/react/pages/Hoge.tsx を作成する

    import React from 'react';
    
    export const Hoge = () => {
      return (
        <>
          <div>ほげページ</div>
        </>
      );
    };
    
  2. app/javascript/react/AppRoutes.tsx を修正する

    import React from 'react';
    import { Routes, Route } from 'react-router-dom';
    import { Top } from './pages/Top';
    import { Hoge } from './pages/Hoge';
    
    export const AppRoutes = () => {
      return (
        <>
          <Routes>
            <Route path="/" element={<Top />} />
            <Route path="/hoge" element={<Hoge />} />
          </Routes>
        </>
      )
    };
    

404ページを作成する

404ページを作成する場合も、新しいファイルとルーティングを追加するだけでできます。
<Route path="*" element={<NotFound />} /> をルーティングの一番下に追加するということが大事です!

  1. app/javascript/react/pages/NotFound.tsx を作成する

    import React from 'react';
    
    export const NotFound = () => {
      return (
        <>
          <div>404</div>
        </>
      );
    };
    
  2. app/javascript/react/AppRoutes.tsx を修正する

    import React from 'react';
    import { Routes, Route } from 'react-router-dom';
    import { Top } from './pages/Top';
    import { Hoge } from './pages/Hoge';
    import { NotFound } from './pages/NotFound';
    
    export const AppRoutes = () => {
      return (
        <>
          <Routes>
            <Route path="/" element={<Top />} />
            <Route path="/hoge" element={<Hoge />} />
            <Route path="*" element={<NotFound />} />
          </Routes>
        </>
      )
    };
    

終わり

あとは、普段通りにReactを書いていけばOKです!