はじめに
ログイン画面のパスワード入力フォームに文字数をチェックする機能を実装しました。後から見返すことができるように、そのやり方を記載します。
前提条件
- この記事ではバージョンが17.0.2のReactを使っています。
- Typescriptをインストールしています。
- アイコンの画像はMaterial UIから拾ってきました。
- スタイリングに関しての記述は省略します。
- ログイン認証をおこなう方法は、この記事では説明しておりません。
目次
画面のレイアウトを作成する
メールアドレスとパスワードの2つの入力フォームを備えたログイン画面を作成します。
パスワードはボタンのクリックに対応して、表示・非表示を切り替えることができるようにします。
import React, { useState } from "react";
// NOTE >> パスワードの表示・非表示をアイコンで示すため、Material UIからアイコンをインポートします
import { Visibility, VisibilityOff } from "@mui/icons-material";
const Login = () => {
const [email, setEmail] = useState<string>("");
// NOTE >> lengthCheck:パスワード入力フォームにおける文字数のチェック結果が記録されます。
// NOTE >> patternCheck:パスワード入力フォームにおける文字種類のチェック結果が記録されます。
const [password, setPassword] = useState<{
lengthCheck: boolean;
patternCheck: boolean;
input: string;
}>({
lengthCheck: true,
patternCheck: true,
input: "",
});
const [showPassword, setShowPassword] = useState<boolean>(false);
return (
<div>
<form>
<div>
<label>メールアドレス</label>
<input
type="email"
value={email}
onChange={(event: React.ChangeEvent<HTMLInputElement>) => {
setEmail(event.target.value);
}}
required
/>
</div>
<div>
<label>パスワード</label>
<input
type={showPassword ? "text" : "password"}
onChange={(event: React.ChangeEvent<HTMLInputElement>) => {
setPassword(checkPassword(event));
}}
required
/>
<button onClick={() => {setShowPassword(!showPassword);}}>
{showPassword ? (<Visibility />) : (<VisibilityOff />)}
</button>
{password.patternCheck === false && (
<p>パスワードに使用できない文字が入力されています</p>
)}
{password.lengthCheck === false && (
<p>パスワードの入力文字数は8文字以上20文字以下です</p>
)}
</div>
<button disabled={!email || !password.input || !password.lengthCheck}>
ログイン
</button>
</form>
</div>
);
};
export default Login;
パスワードについて
ステートpassword
にはlengthCheck
、patternCheck
,input
の3つのプロパティを持たせています。
lengthCheck
→入力された文字数のチェック結果をboolean
で記録します
patternCheck
→入力された文字種類のチェック結果をboolean
で記録します
input
→入力された文字をstring
で記録します。
パスワードの表示・非表示について
ステートshowPassword
でboolean
として管理します。
以下のとおり、アイコンボタンをクリックすることで表示・非表示を切り替えられるようにします。
アイコンボタンのアイコンは、showPassword
の値に対応して、<Visibility />
と<VisibilityOff />
とで切り替えるようにします。
<button onClick={() => {setShowPassword(!showPassword);}}>
{showPassword ? (<Visibility />) : (<VisibilityOff />)}
</button>
パスワードをチェックする関数を作成する
パスワードをチェックする関数は以下のとおりです。
import React from "react";
export const checkPassword = (event: React.ChangeEvent<HTMLInputElement>) => {
const checkedResults: {
lengthCheck: boolean;
patternCheck: boolean;
input: string;
} = {
lengthCheck: true,
patternCheck: true,
input: "",
};
// NOTE >> lengthCheckとpatternCheckの両方がtrueのとき、approvalをtrueにします
const checkApproval = () => {
if (checkedResults.lengthCheck && checkedResults.patternCheck) {
checkedResults.input = event.target.value;
} else {
checkedResults.input = "";
}
};
// NOTE >> 入力文字数をチェックします
const length = event.target.value.length;
if ((length > 0 && length < 8) || length > 20) {
checkedResults.lengthCheck = false;
} else {
checkedResults.lengthCheck = true;
checkApproval();
}
// NOTE >> 入力文字のパターンをチェックします
// NOTE >> regexはRegular Expressionの略です
const regex = /^[a-z|A-Z|0-9|_]+$/;
if (length === 0) {
checkedResults.patternCheck = true;
} else {
checkedResults.patternCheck = regex.test(event.target.value);
checkApproval();
}
return checkedResults;
};
正規表現だけでも、文字数が不足した場合や、許可されていない文字種類が入力された場合にfalse
を返すことができますが、今回は以下のとおり、入力エラーの内容に応じて、JSXに警告文を表示したいため、あえてステートで管理するようにしています。
{password.patternCheck === false && (
<p>パスワードに使用できない文字が入力されています</p>
)}
{password.lengthCheck === false && (
<p>パスワードの入力文字数は8文字以上20文字以下です</p>
)}