10/13 文字を入力してもバリデーションが出てしまう、ログが出ない ![](https://i.imgur.com/YVLv5rh.png) 10/20 追記 ```typescript= const handleClickButton = () => { console.log('入力の確認', { values }); }; return ( <> // ↓ handleSubmitに書き換え <Box {...{handleSubmit}} sx={{ textAlign: "center", m: 0 }}> <Box sx={{ mt: 8, mb: 5 }}> <h2>アカウント新規登録</h2> </Box> <BasicCard> ``` ![](https://i.imgur.com/NhPHTVE.png) ```typescript= <PrimaryButton handleClickButton={handleClickButton} /* handleClickButton={handleSubmit(onSubmit)} * これを書くとバリデーションは効くが文字を入力しても適応される *  そりゃボタンタグだけだからそうなると思っている */ text={"登録"} color={theme.palette.primary.main} textColor={theme.palette.textSecondary.main} /> ``` ![](https://i.imgur.com/Yejfwp6.png) --- --- --- package.json ```json= "@types/react-dom": "^18.0.0", "react": "^18.2.0", "react-dom": "^18.2.0", "react-hook-form": "^7.34.2", // 追加 "react-router-dom": "6", "react-scripts": "5.0.1", "typescript": "^4.4.2", ``` Input.tsx ```typescript= import React from "react"; import Box from "@mui/material/Box"; import TextField from "@mui/material/TextField"; type Prop = { name: string; label: string; handleChangeText: (text: React.ChangeEvent<HTMLInputElement>) => void; }; // ↓追加 type Input = { required: string; maxLength: string; maxNumber: number; }; // ここまで const Input: React.FC<Prop> = ({ name, label, handleChangeText }) => { const [values, setValues] = React.useState(""); return ( <Box component="form" sx={{ "& > :not(style)": { mt: 1, mb: 1, width: 1 }, }} noValidate autoComplete="off" > <TextField id={label} name={name} label={label} variant="outlined" onChange={(e: React.ChangeEvent<HTMLInputElement>) => { setValues(e.target.value); handleChangeText(e); }} value={values} /> </Box> ); }; export default Input; ``` SignUpForm.tsx ```typescript= import React from "react"; import Input from "../atoms/Input"; import PasswordInput from "../atoms/PasswordInput"; import PrimaryButton from "../atoms/PrimaryButton"; import { Box } from "@mui/system"; import CheckboxForm from "../atoms/CheckboxForm"; import Or from "../atoms/Or"; import { CardContent } from "@mui/material"; import BasicCard from "../atoms/BasicCard"; import { theme } from "../../style/theme"; import { useForm, SubmitHandler } from 'react-hook-form'; // 追加 type State = { name: string; mail: string; password: string; isAgreement: boolean; }; const SignUpForm: React.FC = () => { const [values, setValues] = React.useState<State>({ name: "", mail: "", password: "", isAgreement: false, }); // ↓追加 const { register, handleSubmit, formState: { errors }, } = useForm<State>({ mode: "onChange", criteriaMode: "all", shouldFocusError: false, }); // ここまで const handleStateInputChange = (e: React.ChangeEvent<HTMLInputElement>) => { const { name, value } = e.target; setValues({ ...values, [name]: value }); }; // ↓追加 const onSubmit: SubmitHandler<State> = (data) => console.log(data); // ↑ const handleStateIsAgreementChange = ( e: React.SyntheticEvent<Element, Event>, checked: boolean ) => { setValues({ ...values, isAgreement: checked }); }; const handleClickButton = () => { console.log({ values }); }; return ( <> // ↓追加 <Box onSubmit={handleSubmit(onSubmit)} sx={{ textAlign: "center", m: 0 }}> <Box sx={{ mt: 8, mb: 5 }}> <h2>アカウント新規登録</h2> </Box> <BasicCard> <CardContent sx={cardContentStyle}> <Input  // ↓追加 {...register("name", { required: true })} name={"name"} label={"名前"} handleChangeText={handleStateInputChange} />  // ↓追加 {errors.name?.types?.required && <p>文字が入力されていません</p>} <Input  // ↓追加 {...register("mail", { maxLength: 5 })} name={"mail"} label={"メールアドレス"} handleChangeText={handleStateInputChange} /> <PasswordInput handleChangePassword={handleStateInputChange} /> <Box sx={{ textAlign: "left" }}> <CheckboxForm label={"利用規約に同意する"} handleChangeCheck={handleStateIsAgreementChange} checked={values.isAgreement} /> </Box> <PrimaryButton handleClickButton={handleClickButton} text={"登録"} color={theme.palette.primary.main} textColor={theme.palette.textSecondary.main} /> <Or /> <PrimaryButton handleClickButton={handleClickButton} text={"LINEで登録"} color={theme.palette.line.main} textColor={theme.palette.textSecondary.main} /> </CardContent> </BasicCard> </Box> </> ); }; const cardContentStyle = { gap: 2, display: "flex", flexDirection: "column", }; export default SignUpForm; ``` イメージ用スクリーンショット ![](https://i.imgur.com/p4XLAeO.png)