React router vite

ReactとNestでWebアプリケーションを作る5回目です。 最初からやりたい場合はナビゲーションから初回を開いてください。

今回はReactに入力した値をデータベースに保存できるようにしていきます。 そのためにで複数の種類のページを作れるようにします。

今回はアンケートを取れるアプリケーションを作るので、アンケートを投稿するページと、アンケート結果を閲覧するページが必要です。

まずはReactで複数の種類のページを作れるように、React Routerを入れます。 ターミナルでmyreactappディレクトリで以下を実行します。

npm i react-router-dom --prefix front

続いて、アンケートを表す型を作成します。 myreactapp/front/src/models というディレクトリを作成して Enquete.ts というファイルを作成します。

export default class Enquete {
  public id: number = 0
  public point: number = 0
  public message: string = ""
  public mail: string = ""
  public editing: boolean = true;
}

続いて、アンケートを登録するページを作っていきます。 myreactapp/front/src に Enquete.tsx というファイルを作成します。 内容は以下です。

import { ChangeEvent, useState} from 'react'; 
import Enquete from './models/Enquete';
export default function EnquetePage() {
  const [enquete, setEnquete] = useState(new Enquete());
  const [enqueteSended, setEnqueteSended] = useState(false);

  function enqueteChanged(event: ChangeEvent<HTMLInputElement> | ChangeEvent<HTMLTextAreaElement>) {
    setEnquete({...enquete, [event.target.name]:event.target.value});
  }
  async function sendEnquete(){
    await fetch('/api/enquetes', { 
      method: 'POST',
      headers: {'Content-Type': 'application/json'},
      body: JSON.stringify(enquete)
    });
    setEnqueteSended(true);
  }
  let workArea;
  if(enqueteSended) {
    workArea = <p>アンケートの送信をありがとうございました</p>
  } else if (enquete.editing) {
    workArea = <p><button onClick={() => { setEnquete({ ...enquete, editing: false }) }}>確認</button></p>
  } else {
    workArea = <p><button onClick={() => { setEnquete({ ...enquete, editing: true }) }}>キャンセル</button><button onClick={sendEnquete}>送信</button></p>
  }
  return (
    <div>
        <p>アンケート登録</p>
        <p>点数:<input type="number" name="point"  min="1" max="5" onChange={enqueteChanged} disabled={!enquete.editing}></input></p>
        <p>メッセージ:<textarea name="message" onChange={enqueteChanged} disabled={!enquete.editing}></textarea></p>
        <p>メールアドレス:<input type="mail" name="mail" onChange={enqueteChanged} disabled={!enquete.editing}/></p>
      {workArea}
    </div>
  );
}

このページを、/enquete/new にアクセスしたら表示するようにします。 myreactapp/front/src/main.tsx を変更します。

import React from 'react'
import {createRoot} from 'react-dom/client' //この行を削除
import ReactDOM from 'react-dom/client' //この行を追加
import { Route, createBrowserRouter, RouterProvider, createRoutesFromElements } from "react-router-dom";// この行を追加
import App from './App.tsx'
import './index.css'
import EnquetePage from './Enquete.tsx'// この行を追加

//ここから
//createRoot(document.getElementById('root')!).render(
//  <StrictMode>
//    <App />
//  </StrictMode>,
//ここまでを削除

const router = createBrowserRouter(// この行から
  createRoutesFromElements(
    <>
      <Route path="/" element={<App />} />
      <Route path="/enquete/new" element={<EnquetePage />} />
    </>
  )
);// ここまでを追加

ReactDOM.createRoot(document.getElementById('root')!).render(
  <React.StrictMode>
    <RouterProvider router={router} />{/* この行を変更 */}
  </React.StrictMode>,
)

これでアプリを起動します。 今起動していた場合は Ctrl+C で停止してからmyreactappで以下のコマンドを実行してください。

npm run watch

これで http://localhost:5173/enquete/new にアクセスしてみてください。

以下のような画面が表示されれば成功です。 アンケート登録 動作確認をしていきます。 アンケートに適当な値を入れて アンケート入力 確認ボタンを押して、 アンケート入力 送信ボタンを押します。 アンケート送信 上記のように動けば画面はうまく行っています。 データベースに登録できているか確認します。 ターミナルを開いて、以下のコマンドを実行してください。

podman exec -it postgres psql -U postgres

下のような表示がされるので、

postgres=# 

select * from enquete; と入力します。

postgres=# select * from enquete;
 id | point | message  |     mail      
----+-------+----------+---------------
  1 |     1 | よいね。 | a@example.com
(1 row)
postgres=# 

このように、アンケートがデータベースに登録されていることが確認できます。 これでデータベースにアンケートを登録することができました! 次は認証とともに登録されたアンケートを一覧で確認する機能を作っていきます。