Genie

学んだ事

reactでログインフォーム作成

 

1.Reactでログインフォームを作成する方法

githubに完成形があります。

github.com

環境
node 20.11.1

npm 10.4.0


mkdir login-formと空のフォルダを作成し、cd login-formにディレクトリ移動

create-react-app login-form
と入力しreactの雛形を作成します。


概要としては、ログインフォームをHTMLタグで作成し、
ユーザー名、メールアドレス、パスワードは<div>タグで作成します。
その下にログインボタンを設置し、
最後にログインに成功しましたのpタグを用意します。
そしてそれぞれのdivタグの中にlabelが存在し、inputタグを作成します。

 

1.HTMLの雛形を作成

src/App.jsをこのように編集します。

import './App.css';

function App() {
  return (
    <div className="formContainer">
      <form>
        <h1>ログインフォーム</h1>
        {/* <hr /> #横線を引くタグ# */}
        <hr />
        <div className="uiform">
          <div className="formField">
            <label>ユーザー名</label>
            <input type="text" placeholder="ユーザー名" name="username" />
          </div>
          <div className="formField">
            <label>メールアドレス</label>
            <input type="email" placeholder="メールアドレス" name="email" />
          </div>
          <div className="formField">
            <label>パスワード</label>
            <input type="password" placeholder="パスワード" name="password" />
          </div>
        </div>
      </form>
    </div>
  );
}

export default App;
 

npm startでローカルサーバーを立ち上げるとこのようなフォームになります。
次にdivタグの下にログインボタンを作成します。
 
          </div>
        </div>
        <button className="submitButton">ログイン</button>
      </form>
    </div>

このようにログインボタンが追加され、HTMLの雛形の作成が終わりました。
 

2: CSSの雛形作成

それではsrc/App.cssを一回初期化し、
bodyに
body {
  background: rgb(0,249,255);
  background: linear-gradient(90deg, rgba(0,249,255,1) 0%,
 rgba(2,155,156,1) 85%, rgba(0,212,255,1) 100%);
  overflow-y: hidden;
}

.formContainer {
  height: 100vh;
}
と入力します。
bodyの背景色はCSS Gradientで

cssgradient.io

を使いました。

overflow-y: hiddenに解説ですが、height: 100vhで高さを合わせるとwebページがスクロールできてしまうので、はみ出た分を隠す為のプロパティを入力します。

そうしましたら、.formContainerを編集します。

body {
  background: rgb(0,249,255);
  background: linear-gradient(90deg, rgba(0,249,255,1) 0%,
  rgba(2,155,156,1) 85%, rgba(0,212,255,1) 100%);
  overflow-y: hidden;
}

.formContainer {
  height: 100vh;
  width: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
}

height; 100vh;は高さを合わせる。

widht: 100%は横いっぱい使う。

align-items: で縦をセンターにし、

justify-content: centerで横をセンターにしまう。

そしたらこのようなログインフォーム真ん中によった画面になります。

 

次に真っ白なフォームを作成します。

.formContainer form {
  background-color: white;
  width: 70%;  
}

 

 background-color: whiteはバックグラウンドを白にしまう。

widht: 70%の意味は今のブラウザの70%分の横幅を取るという意味です。

なのでブラウザを大きくした場合はその大きくした画面の70%分の画面を取ります。

ですが、大きすぎてもいけない場合もあるので、

上限を設定します。

.formContainer form {
  background-color: white;
  width: 70%;  
  max-width: 450px;
}

max-widht: 450pxと設定することによって、

widthで70%表示したとしても、上限として450ピクセル(px)までしか表示できないように出来ます。

 

 そしたらログインフォームのおしゃれにしたいので、

paddingとborder-radiusを追加します。

.formContainer form {
  background-color: #f8ecec;
  width: 70%;  
  max-width: 450px;
  padding: 30px;
  border-radius: 10px;
  border: 1px solid #dfdfdf;
}

 padding: 30pxで内側の枠を広げます。

 border-radius: 10pxで角に丸みを出します。

border: 1px solid #dfdfdf;でボーダーの枠の線の色を変更します。

 

 box-shadowを追加しますが、今回は便利なサイトがあるので、こちらを使います。

 

 

hiroyuki-n.github.io

 

こちらでお好みのbox-shadowを作成して、影を作ります。

.formContainer form {
  background-color: #f8ecec;
  width: 70%;  
  max-width: 450px;
  padding: 30px;
  border-radius: 10px;
  border: 1px solid #dfdfdf;
  box-shadow: 34px 35px 61px -31px #777777;
  border-radius: 13px;
}


このような画面になります。

今の画面だと左に側によってしまっているので、真ん中の縦に綺麗に並ぶように整形します。
こちらはflexの知識が必要なので改めてやっていきます。
display: flexは全て横並びになるという意味です。
ですので、
flex-direction: column;で縦並びにします。
collumnというのは縦という意味です。
そしたら
align-items: center;が充てることができ、
justify-content: space-evenly;

.uiform {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: space-evenly;
  height: 400px;
}

追加で ログインフォームを中央に寄せたいので、

h1 {
  text-align: center;
}

 とCSSを当てます。

 

 次にユーザー名とinputの枠が横並びになっているので変更します。

こちらも先ほどと同じようにdisplay: flex;を使います。

.formField {
  display: flex;
  flex-direction: column;
}

そしたら縦並びになります。

そしたら、width: 100%を追加してください。

これは親要素に対して100%を取るので、ユーザー名に対して、100%取るようになります。

.formField {
  display: flex;
  flex-direction: column;
  width: 100%;
}

 

formFieldのinputタグを変更します。

.formField input {
  border: 1px solid grey;
  padding: 20px;  
  border-radius: 4px;
}

 border:1px solid grey;で枠の色をgreyに変更します。

padding: 20px;で枠を広げます。

border-radius: 4px;で枠を丸くします。

次にinputタグをクリックすると、枠が黒くなってしまうので、無効にします。

.formField input:focus {
  outline: none;
}

 

次にlabelを変更します。

.formField label {
  font-size: 15px;
  font-weight: 600;
  margin-bottom: 3px;
}

 labelの文字のサイズが変更されました。

次にログインボタンが簡素な形になっていますので変更します。

button {
  background-color: #1b66a7;
  width: 100%;
  margin-top: 10px;
  border: none;
  border-radius: 5px;
  padding: 10px 30px;
  color: white;
  font-size: 15px;
  cursor: pointer;
}

 backgroun-colorで色指定

widht:100%で使う範囲設定

margin-top:10pxでマージンを取ります。

border:none;

padding:で縦横を広げます。

color: white;で文字の色を白

font-size: 15pxで文字の大きさ変更

cursor: pointerでカーソルが当たった時、ポインターになるようにします。

いい感じのログインボタンになりました。

最後にbuttonにホバーした時の挙動を加えます。

button {
  background-color: #1b66a7;
  width: 100%;
  margin-top: 10px;
  border: none;
  border-radius: 5px;
  padding: 10px 30px;
  color: white;
  font-size: 15px;
  cursor: pointer;
  transition: all 0.2s;
}

button:hover {
  background-color: #124877;
}

 これでCSSの設定はある程度は完成です。追加で必要なCSSもありますが、その都度追加します。

 

3.入力フォームのバリデーションチェック

例えば、ユーザー名が長すぎる場合、メールアドレスに@が含まれてない場合、パスワードが短すぎる場合にエラーを出したりします。

これをreact/javascriptで実装していきます。

方法としてはデータベースなどに格納するのですが、今回は状態変数をreactのhooksのuseStateで格納していきます。

src/App.jsに以下を追加します。

function App() {
  const initialValues = { username: "", mailAddress: "", password: "" };
  const [formValues, setFormValues] = useState(initialValues);

useStateフックの利用で関数コンポーネント内で状態管理を可能とするフックを設定します。useState(initialValues)ではinitialValuesのこの状態を初期値として設定し、

{ username: "", mailAddress: "", password: ""}というオブジェクトとして設定します。

状態宣言においては[formValues, setValues]で分割代入を使っています。

formValuesでは現在のフォームの状態を保持し、setFormValuesではその状態の更新をする為の関数になっています。

なので、initialValuesは'username','mailAddress','password'の各フィールドが空の文字列で初期化されています。

import './App.css';
import { useState } from 'react';

function App() {
  const initialValues = { username: '', mailAddress: '', password: '' };
  const [formValues, setFormValues] = useState(initialValues);

  const handleChange = (e) => {
    const { name, value } = e.target;
    setFormValues({ ...formValues, [name]: value });
  };
  return (
    <div className="formContainer">
      <form>
        <h1>ログインフォーム</h1>
        {/* <hr /> #横線を引くタグ# */}
        <hr />
        <div className="uiform">
          <div className="formField">
            <label>ユーザー名</label>
            <input
              type="text"
              placeholder="ユーザー名"
              name="username"
              onChange={(e) => handleChange(e)}
            />
          </div>
          <div className="formField">
            <label>メールアドレス</label>
            <input
              type="email"
              placeholder="メールアドレス"
              name="mailAddress"
              onChange={(e) => handleChange(e)}
            />
          </div>
          <div className="formField">
            <label>パスワード</label>
            <input
              type="password"
              placeholder="パスワード"
              name="password"
              onChange={(e) => handleChange(e)}
            />
          </div>
        </div>
        <button className="submitButton">ログイン</button>
      </form>
    </div>
  );
}

export default App;

 

 例えば、nameの変数ですが、

          <div className="formField">
            <label>ユーザー名</label>
            <input
              type="text"
              placeholder="ユーザー名"
              name="username"
              onChange={(e) => handleChange(e)}
            />
          </div>

のname="username"のvalueに"tarou"と入力されれば、

const initialValues = { username: '', mailAddress: '', password: '' };

のusernameに格納されます。

これでinputを入力することでusernameやmailAddressを格納することができました。

最後に送信ボタンを押した時にログインを送信するように設定していきます。

今回はAPIを叩くような事はしませんが、バリエーションチェックのみを行っていきます。