#現在の状況
React x TypeScript x Laravel x Material-ui x styled-componentsで認証機能付きのtoDoアプリを作成しようとしています。
ログイン時にはメールアドレスとパスワードが存在し、どちらもバリデーションを行いたいです。
とりあえず空欄の場合にエラーメッセージが出るようにしたいのですが、空欄だとそのままバックエンド側に送信してしまいます。
これを直したいです
#試したこと
Controllerを用いて外部コンポーネントの制御などもやってみたのですがうまく行きませんでした。
直接記述すればエラーメッセージ自体は表示されます。
login関数以外の無名関数にした場合がしっかりバリデーションが行われているのでここが原因だと思うのですが分かりません。
静的サイトのコンタクトページで使用した際はTypeScriptで書いてもうまくいったのですが、なぜ動かないのか分かりません。
どなたかわかる方がいたら教えていただけると助かります。
下記にコードを載せます。
Controllerの部分はコメントアウトしてありますが、試したことの形跡として残しておきます
React
1import { useState, useEffect } from "react"; 2import { useHistory } from "react-router"; 3import { useAuthContext } from "../../providers/AuthProvider"; 4import { Controller, SubmitHandler, useForm } from "react-hook-form"; 5import TextField from "@material-ui/core/TextField"; 6import axios from "axios"; 7import styled from "styled-components"; 8import { Button, Card, InputBase } from "@material-ui/core"; 9 10type formType = { 11 email: string; 12 password: string; 13}; 14 15export const Login = () => { 16 const [email, setEmail] = useState(""); 17 const [password, setPassword] = useState(""); 18 const { setIsLogin } = useAuthContext(); 19 const history = useHistory(); 20 const { 21 watch, 22 control, 23 register, 24 handleSubmit, 25 formState: { errors }, 26 setValue, 27 } = useForm<formType>(); 28 29 useEffect(() => { 30 setEmail(watch("email")); 31 }, [watch("email")]); 32 33 useEffect(() => { 34 setPassword(watch("password")); 35 }, [watch("password")]); 36 // alert("もうやだ"); 37 type eventType = { 38 e: React.FormEvent<HTMLFormElement>; 39 }; 40 41 const login: SubmitHandler<eventType> = async (props) => { 42 const { e } = props; 43 e.preventDefault(); 44 45 try { 46 // ログイン時にCSRFトークンを初期化 47 await axios.get("/sanctum/csrf-cookie"); 48 try { 49 const res = await axios.post("/api/login", { 50 email, 51 password, 52 }); 53 if (res.data.result) { 54 console.log("login:ログイン成功"); 55 setIsLogin(true); 56 history.push({ pathname: "/home" }); 57 } else { 58 console.log("login:ログイン失敗"); 59 console.log(res.data.message); 60 } 61 } catch (err) { 62 console.log("login:接続に失敗しました"); 63 console.log(err); 64 } 65 } catch (error) { 66 console.log("login:CSRFトークンの初期化に失敗しました"); 67 console.log(error); 68 } 69 }; 70 return ( 71 <SComponentContainer> 72 <Card> 73 <form 74 // onSubmit={(e) => handleSubmit(login({ e }))} 75 // onSubmit={handleSubmit((data) => alert(data))} 76 onSubmit={(e) => handleSubmit(login({ e }))} 77 id="contact-form" 78 > 79 <STextField 80 label="メールアドレス" 81 type="email" 82 variant="filled" 83 fullWidth 84 margin="normal" 85 // inputProps={{ 86 // ...register("email", { required: true }), 87 // }} 88 {...register("email", { required: true })} 89 // inputRef ={register("email", { required: true })} 90 error={Boolean(errors.email)} 91 helperText={ 92 errors.email && "メールアドレスを入力してください" 93 } 94 // onChange={(e) => setEmail(e.target.value)} 95 /> 96 {/* <Controller 97 name="email" 98 control={control} 99 rules={{ required: true }} 100 render={(props) => ( 101 <STextField 102 id="email" 103 label="メールアドレス" 104 type="email" 105 variant="filled" 106 fullWidth 107 margin="normal" 108 // inputProps={{ 109 // ...register("email", { required: true }), 110 // }} 111 // {...register("email", { required: true })} 112 error={Boolean(errors.email)} 113 helperText={ 114 errors.email && 115 "メールアドレスを入力してください" 116 } 117 // onChange={(e) => setEmail(e.target.value)} 118 /> 119 )} 120 /> */} 121 <STextField 122 variant="filled" 123 label="パスワード" 124 type="password" 125 fullWidth 126 margin="normal" 127 // inputProps={{ 128 // ...register("password", { required: true }), 129 // }} 130 {...register("password", { required: true })} 131 error={Boolean(errors.password)} 132 helperText={ 133 errors.password && "パスワードを入力してください" 134 } 135 // onChange={(e) => setPassword(e.target.value)} 136 /> 137 {/* <Controller 138 name="password" 139 control={control} 140 rules={{ required: true }} 141 render={(props) => ( 142 <STextField 143 label="パスワード" 144 type="password" 145 variant="filled" 146 fullWidth 147 margin="normal" 148 // inputProps={{ 149 // ...register("password", { required: true }), 150 // }} 151 // { 152 // ...register("password", { required: true }),} 153 // {...register("password", { required: true })} 154 error={Boolean(errors.password)} 155 helperText={ 156 errors.password && 157 "パスワードを入力してください" 158 } 159 // onChange={(e) => setEmail(e.target.value)} 160 /> 161 )} 162 /> */} 163 {console.log(email, password)} 164 <Button type="submit" color="default" variant="contained"> 165 Login 166 </Button> 167 </form> 168 </Card> 169 </SComponentContainer> 170 ); 171}; 172 173const SComponentContainer = styled.div` 174 width: 100%; 175 margin: 0 auto; 176 max-width: 80vw; 177`; 178 179const SCard = styled.div` 180 width: 80; 181`; 182const SButton = styled(Button)` 183 background-color: blue; 184 color: white; 185`; 186 187const STextField = styled(TextField)` 188 background-color: white; 189 color: black; 190 .MuiInputLabel-root { 191 background-color: skyblue; 192 ::placeholder { 193 color: red; 194 } 195 /* color: black; */ 196 } 197`; 198
あなたの回答
tips
プレビュー