Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 |
Tags
- JavaScript
- TypeScript
- 리액트
- 토이 프로젝트
- 프론트엔드
- Supabase
- revalidatepath
- Form
- tailwind
- styled component
- 코딩테스트
- 동적계획법
- react router dom
- React
- reduxtoolkit
- React Query
- 리덕스
- 토이프로젝트
- 코테
- 프로그래머스
- react pattern
- 자바스크립트
- tanstack query
- 리액트 패턴
- 리액트 라우터 돔
- 그리디
- Next.js
- 코어자바스크립트
- 스택
- 타입스크립트
Archives
- Today
- Total
느려도 한걸음씩
React로 Form다루기 (7) - useIntput 커스텀훅 제작 본문
import { useState } from "react";
import Input from "./Input";
import { isEmail, isNotEmpty, hasMinLength } from "../util/validation.js";
export default function StateLogin() {
const [enteredValue, setEnteredValue] = useState({
email: "",
password: "",
});
const [didEdit, setDidEdit] = useState({
email: false,
password: false,
});
function handleSubmit(e) {
e.preventDefault();
console.log(enteredValue);
}
function handleInputChange(identifier, e) {
setEnteredValue((prev) => ({
...prev,
[identifier]: e.target.value,
}));
setDidEdit((prevEdit) => ({
...prevEdit,
[identifier]: false,
}));
}
function handleInputBlur(identifier) {
setDidEdit((prevEdit) => ({
...prevEdit,
[identifier]: true,
}));
}
const emailsIsInvalid =
didEdit.email &&
!isEmail(enteredValue.email) &&
!isNotEmpty(enteredValue.email);
const passwordIsInValid =
didEdit.password && hasMinLength(enteredValue.password);
return (
<form onSubmit={handleSubmit}>
<h2>Login</h2>
<div className='control-row'>
<Input
label='Email'
id='email'
type='email'
name='email'
onBlur={() => handleInputBlur("email")}
onChange={(e) => handleInputChange("email", e)}
value={enteredValue.email}
error={emailsIsInvalid && "Please enter a valid email"}
/>
<Input
id='password'
label='Password'
type='password'
name='password'
onBlur={() => handleInputBlur("password")}
value={enteredValue.password}
onChange={(e) => handleInputChange("password", e)}
error={passwordIsInValid && "Please enter a valid password"}
/>
</div>
<p className='form-actions'>
<button className='button button-flat'>Reset</button>
<button className='button'>Login</button>
</p>
</form>
);
}
state, 함수, 유효성 검사 변수를 커스텀훅으로 관리해보자
import { useState } from "react";
export default function useInput(initialValue, validationFn) {
const [enteredValue, setEnteredValue] = useState(initialValue);
const [didEdit, setDidEdit] = useState(false);
const valueValid = validationFn(enteredValue);
function handleInputChange(e) {
setEnteredValue(e.target.value);
setDidEdit(false);
}
function handleInputBlur() {
setDidEdit(true);
}
return {
value: enteredValue,
hasError: didEdit && !valueValid,
handleInputChange,
handleInputBlur,
};
}
import { useState } from "react";
import Input from "./Input";
import { isEmail, isNotEmpty, hasMinLength } from "../util/validation.js";
export default function StateLogin() {
const [enteredValue, setEnteredValue] = useState({
email: "",
password: "",
});
const [didEdit, setDidEdit] = useState({
email: false,
password: false,
});
function handleSubmit(e) {
e.preventDefault();
console.log(enteredValue);
}
function handleInputChange(identifier, e) {
setEnteredValue((prev) => ({
...prev,
[identifier]: e.target.value,
}));
setDidEdit((prevEdit) => ({
...prevEdit,
[identifier]: false,
}));
}
function handleInputBlur(identifier) {
setDidEdit((prevEdit) => ({
...prevEdit,
[identifier]: true,
}));
}
const emailsIsInvalid =
didEdit.email &&
!isEmail(enteredValue.email) &&
!isNotEmpty(enteredValue.email);
const passwordIsInValid =
didEdit.password && hasMinLength(enteredValue.password);
return (
<form onSubmit={handleSubmit}>
<h2>Login</h2>
<div className='control-row'>
<Input
label='Email'
id='email'
type='email'
name='email'
onBlur={() => handleInputBlur("email")}
onChange={(e) => handleInputChange("email", e)}
value={enteredValue.email}
error={emailsIsInvalid && "Please enter a valid email"}
/>
<Input
id='password'
label='Password'
type='password'
name='password'
onBlur={() => handleInputBlur("password")}
value={enteredValue.password}
onChange={(e) => handleInputChange("password", e)}
error={passwordIsInValid && "Please enter a valid password"}
/>
</div>
<p className='form-actions'>
<button className='button button-flat'>Reset</button>
<button className='button'>Login</button>
</p>
</form>
);
}
import Input from "./Input";
import { isEmail, isNotEmpty, hasMinLength } from "../util/validation.js";
import useInput from "../hooks/useInput.js";
export default function StateLogin() {
const {
value: emailValue,
handleInputChange: hnadleEmailChange,
handleInputBlur: handleEmailBlur,
hasError: emailHasError,
} = useInput("", (value) => isEmail(value) && isNotEmpty(value));
const {
value: passwordValue,
handleInputChange: handlePasswordChange,
handleInputBlur: handlePasswordBlur,
hasError: passwordHasError,
} = useInput("", (value) => hasMinLength(value, 6));
function handleSubmit(e) {
e.preventDefault();
if (emailHasError || passwordHasError) {
return;
}
console.log(emailValue, passwordValue);
}
return (
<form onSubmit={handleSubmit}>
<h2>Login</h2>
<div className='control-row'>
<Input
label='Email'
id='email'
type='email'
name='email'
onBlur={handleEmailBlur}
onChange={hnadleEmailChange}
value={emailValue}
error={emailHasError && "Please enter a valid email"}
/>
<Input
id='password'
label='Password'
type='password'
name='password'
onBlur={handlePasswordBlur}
value={passwordValue}
onChange={handlePasswordChange}
error={passwordHasError && "Please enter a valid password"}
/>
</div>
<p className='form-actions'>
<button className='button button-flat'>Reset</button>
<button className='button'>Login</button>
</p>
</form>
);
}
코드가 매우 간결해졌고 유지보수하기에 쉬워졌다!
'FE develop > React로 Form 다루기' 카테고리의 다른 글
React로 Form다루기 (9) - 비동기 폼 액션으로 작업하기 (0) | 2025.04.02 |
---|---|
React로 Form다루기 (8) - FormAction으로 폼제출 다루기(useActionState) (0) | 2025.04.02 |
React로 Form다루기 (6) - Form 유효성 검사(폼 제출시) (0) | 2025.04.01 |
React로 Form다루기 (5) - Form 유효성 검사(키보드 입력, blur) (0) | 2025.04.01 |
React로 Form다루기 (4) - Form 초기화 하기 (0) | 2025.04.01 |