React router

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/index.tsx を変更します。

import React from 'react';
import ReactDOM from 'react-dom/client';
import { Route, BrowserRouter, Routes } from "react-router-dom";// この行を追加
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';
import EnquetePage from './Enquete';// この行を追加

const RouterConfig = () => {//この行から

  return (
     <BrowserRouter>
      <Routes>
        <Route index element={<App />} />
        <Route path="/enquete/new" element={<EnquetePage />} />
      </Routes>
    </BrowserRouter>
  );
}//この行までを追加

const root = ReactDOM.createRoot(
  document.getElementById('root') as HTMLElement
);
root.render(
  <>{/* この行を変更 */}
    <RouterConfig /> {/* この行を変更 */}
  </>{/* この行を変更 */}
);

// If you want to start measuring performance in your app, pass a function
// to log results (for example: reportWebVitals(console.log))
// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
reportWebVitals();

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

npm run watch

これで http://localhost:3000/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=# 

このように、アンケートがデータベースに登録されていることが確認できます。

これでデータベースにアンケートを登録することができました!

次は認証とともに登録されたアンケートを一覧で確認する機能を作っていきます。