Reactを使ってフロントバリデージョンを実装する機会があったので、アウトプットします。
今回の目的
入力された値を検証し、エラーメッセージを表示させる関数を作成すること
目次
- 送信フォームを作成
- 値を検証する関数を作成
- 送信ボタンをクリックできなくする
- カスタムフック化
1. 送信フォームを作成
今回は、以下のフォームをベースに実装しております。
- 入力されたフォームの値を管理するStateを作成
- 入力された時、値が更新されるonchangeイベントを実装
- 送信ボタンをクリックした時、入力している値がアラートされる
- CSSフレームワークとして、chakra-uiを採用

import React, { ChangeEvent, useState } from "react";
import { ChakraProvider, Input, Button, Box } from "@chakra-ui/react" ;
export default function App() {
const [inputPost, setInputPost] = useState<string>("")
const onChangePost = (e: ChangeEvent<HTMLInputElement>) => {
const post = e.target.value;
setInputPost(post)
}
const onClickSubmit = () => {
alert(inputPost)
}
return (
<ChakraProvider>
<Box m={16}>
<Input value={inputPost} onChange={onChangePost} w="sm" />
<Button onClick={onClickSubmit} bg="blue.300" color="white">送信する</Button>
</Box>
</ChakraProvider>
);
}
これで、入力した値がアラートされるフォームができました。
ただ、現状では以下の問題点があります。
- 空文字でも送信できる
- 文字数も無制限に入力できる
なので、これを制限していきたいと思います。
2.値を検証する関数を作成
検証用の関数(validateInputPost)を作成して、検証に引っ掛かった場合、エラーメッセージ を表示させます
検証内容
今回の検証内容は、以下の通りです。
- タイトルが空でないか
- タイトルが文字数を超えていないか(今回は8文字)
上記に引っかかる場合、エラー文字を表示させていきます。
プログラムの流れ
想定している流れは、以下の通りです。
- onChangeでstateの値が更新される
- 更新された値を検証する
- 値が想定外だった場合、エラーメッセージを返す
- エラーメッセージ がある場合、それを表示する
実装
1.エラーを保持するstateを作成
const [error, setError] = useState<string>("");
2.検証する関数を作成
const validateInputPost = (inputPost: string) => {
const maxPostLength = 8;
let error = "";
// 制限1.空の場合
if (!inputPost) {
error = "投稿を入力してください";
// 制限2.文字数が8文字より多い場合
} else if (inputPost.length > maxPostLength) {
error = `投稿は${maxPostLength}文字以内で入力してください`;
}
//検証に引っ掛かった時、エラーを保持するstateを更新
setError(error);
};
3.onCahgeイベント時に、検証する関数を実行
const onChangePost = (e: ChangeEvent<HTMLInputElement>) => {
const post = e.target.value;
setInputPost(post);
validateInputPost(post) //これ
};
4.エラーを保持するstateがエラー内容を持っている場合、エラー文字を表示させる
以下のように実装すると、エラー内容を保持している場合のみ、赤文字でエラー文が表示されます。
//エラーの場合: errorにエラー内容が入る
//エラーでない場合: ""が入っている = 表示されない
{ error &&
<Text color="red">{error}</Text>
}
全体
import React, { ChangeEvent, useState } from "react";
import { ChakraProvider, Input, Button, Box, Text } from "@chakra-ui/react";
export default function App() {
const [inputPost, setInputPost] = useState<string>("");
const [error, setError] = useState<string>(""); // 1
const onChangePost = (e: ChangeEvent<HTMLInputElement>) => {
const post = e.target.value;
setInputPost(post);
validateInputPost(post); // 3
};
const onClickSubmit = () => {
alert(inputPost);
};
// 2
const validateInputPost = (inputPost: string) => {
const maxPostLength = 8;
let error = "";
if (!inputPost) {
error = "投稿を入力してください";
} else if (inputPost.length > maxPostLength) {
error = `投稿は${maxPostLength}文字以内で入力してください`;
}
setError(error);
};
return (
<ChakraProvider>
<Box m={16}>
<Input value={inputPost} onChange={onChangePost} w="sm" />
<Button onClick={onClickSubmit} bg="blue.300" color="white">
送信する
</Button>
{error && <Text color="red">{error}</Text>} // 4
</Box>
</ChakraProvider>
);
}
これで、エラー文字が表示されるようになります。


3.送信ボタンをクリックできなくする
- 現状だと、エラーメッセージ を表示させているだけで送信できてしまいます。


-
これでは意味がないので、送信ボタンをクリックできないようにします。今回は
isDisabled
を使用します。(trueの場合、ボタンがクリックできなくなります。) -
isDisabledは、trueであればボタンがクリックできなくなります。なので、
error
に文字が入っている場合、trueになるため、送信することができなくなります。
<Button onClick={onClickSubmit} isDisabled={error} bg="blue.300" color="white">
送信する
</Button>
これでokです!
ボタンが少し透明になって、クリックできなくなります。
実装後


- 最終コード
import React, { ChangeEvent, useState } from "react";
import { ChakraProvider, Input, Button, Box, Text } from "@chakra-ui/react";
export default function App() {
const [inputPost, setInputPost] = useState<string>("");
const [error, setError] = useState<string>("");
const onChangePost = (e: ChangeEvent<HTMLInputElement>) => {
const post = e.target.value;
setInputPost(post);
validateInputPost(post);
};
const onClickSubmit = () => {
alert(inputPost);
};
const validateInputPost = (inputPost: string) => {
const maxPostLength = 8;
let error = "";
if (!inputPost) {
error = "投稿を入力してください";
} else if (inputPost.length > maxPostLength) {
error = `投稿は${maxPostLength}文字以内で入力してください`;
}
setError(error);
};
return (
<ChakraProvider>
<Box m={16}>
<Input value={inputPost} onChange={onChangePost} w="sm" />
<Button onClick={onClickSubmit} isDisabled={error} bg="blue.300" color="white">
送信する
</Button>
{error && <Text color="red">{error}</Text>}
</Box>
</ChakraProvider>
);
}
4.カスタムフック化
最後に、検証用の関数をカスタムフックとして切り出します
import React, { ChangeEvent, useState } from "react";
import { ChakraProvider, Input, Button, Box, Text } from "@chakra-ui/react";
import { usePostValidate } from "./useValidate";
export default function App() {
const [inputPost, setInputPost] = useState<string>("");
const { error, validateInputPost } = usePostValidate();
const onChangePost = (e: ChangeEvent<HTMLInputElement>) => {
const post = e.target.value;
setInputPost(post);
validateInputPost(post);
};
const onClickSubmit = () => {
alert(inputPost);
};
return (
<ChakraProvider>
<Box m={16}>
<Input value={inputPost} onChange={onChangePost} w="sm" />
<Button
onClick={onClickSubmit}
isDisabled={error}
bg="blue.300"
color="white"
>
送信する
</Button>
{error && <Text color="red">{error}</Text>}
</Box>
</ChakraProvider>
);
}
import { useState } from "react";
export const usePostValidate = () => {
const [error, setError] = useState<string>("");
const validateInputPost = (inputPost: string) => {
const maxPostLength = 8;
let error = "";
if (!inputPost) {
error = "投稿を入力してください";
} else if (inputPost.length > maxPostLength) {
error = `投稿は${maxPostLength}文字以内で入力してください`;
}
setError(error);
};
return { validateInputPost, error };
};
同じ挙動になるとOKです。
以上になります。