https://www.udemy.com/course/best-react/
【한글자막】 React 완벽 가이드 with Redux, Next.js, TypeScript
Javascript부터 웹 어플리케이션 배포까지, React와 프론트엔드 최신 기술을 가장 쉽고 확실하게 배우는 법
www.udemy.com
이 게시물은 유데미 React 완벽 가이드 강의를 보고 메모를 남기는 게시물 입니다.
구조분해할당으로 최적화하기
#1. useReducer와 useEffect를 함께 사용한 후 최적화를 하였다.
어떻게 최적화 하였는지 #2 로 넘어가보자.
import React, { useState, useEffect, useReducer } from "react";
import Card from "../UI/Card/Card";
import classes from "./Login.module.css";
import Button from "../UI/Button/Button";
const emailReducer = (state, action) => {
if (action.type === "USER_INPUT") {
return { value: action.val, isVaild: action.val.includes("@") };
}
if (action.type === "INPUT_BLUR") {
return { value: state.value, isVaild: state.value.includes("@") };
}
return { value: "", isVaild: false };
};
const passwordReducer = (state, action) => {
if (action.type === "USER_INPUT") {
return { value: action.val, isVaild: action.val.trim().length > 6 };
}
if (action.type === "INPUT_BLUR") {
return { value: state.value, isVaild: state.value.trim().length > 6 };
}
return { value: "", isVaild: false };
};
const Login = (props) => {
// const [enteredEmail, setEnteredEmail] = useState("");
// const [emailIsValid, setEmailIsValid] = useState();
// const [enteredPassword, setEnteredPassword] = useState("");
// const [passwordIsValid, setPasswordIsValid] = useState();
const [formIsValid, setFormIsValid] = useState(false);
const [emailState, dispatchEmail] = useReducer(emailReducer, {
value: "",
isVaild: null,
});
const [passwordState, dispatchPassword] = useReducer(passwordReducer, {
value: "",
isVaild: null,
});
useEffect(() => {
console.log("EFFECT RUNNING");
return () => {
console.log("EFFECT CLEANUP");
};
}, []);
// 구조분해할당으로 useReducer 와 useEffect를 함께 사용할때 최적화 방법
const { isVaild: emailIsValid } = emailState;
const { isVaild: passwordIsValid } = passwordState;
useEffect(() => {
const identifier = setTimeout(() => {
console.log("Checking form validity!");
setFormIsValid(emailIsValid && passwordIsValid);
}, 500);
return () => {
console.log("CLEANUP");
clearTimeout(identifier);
};
}, [emailIsValid, passwordIsValid]);
const emailChangeHandler = (e) => {
dispatchEmail({ type: "USER_INPUT", val: e.target.value });
// setFormIsValid(e.target.value.includes("@") && passwordState.isVaild);
};
const passwordChangeHandler = (e) => {
dispatchPassword({ type: "USER_INPUT", val: e.target.value });
// setFormIsValid(emailState.isVaild && e.target.value.trim().length > 6);
};
// 이메일 유효성 검사
const validateEmailHandler = () => {
// setEmailIsValid(emailState.isVaild);
dispatchEmail({ type: "INPUT_BLUR" });
};
// 비밀번호 유효성 검사
const validatePasswordHandler = () => {
// setPasswordIsValid(enteredPassword.trim().length > 6);
dispatchEmail({ type: "INPUT_BLUR" });
};
const submitHandler = (event) => {
event.preventDefault();
props.onLogin(emailState.value, passwordState.value);
};
return (
<Card className={classes.login}>
<form onSubmit={submitHandler}>
<div
className={`${classes.control} ${
emailState.isVaild === false ? classes.invalid : ""
}`}
>
<label htmlFor="email">E-Mail</label>
<input
type="email"
id="email"
value={emailState.value}
onChange={emailChangeHandler}
onBlur={validateEmailHandler}
/>
</div>
<div
className={`${classes.control} ${
passwordState.isValid === false ? classes.invalid : ""
}`}
>
<label htmlFor="password">Password</label>
<input
type="password"
id="password"
value={passwordState.value}
onChange={passwordChangeHandler}
onBlur={validatePasswordHandler}
/>
</div>
<div className={classes.actions}>
<Button type="submit" className={classes.btn} disabled={!formIsValid}>
Login
</Button>
</div>
</form>
</Card>
);
};
export default Login;
#2. useReducer의 state로 emailState와 passwordState를 사용중이다.
구조분해할당을 사용하여 최적화를 해보자.
- 객체를 만들어 프로퍼티를 isVaild로 하고 각각 state에 어울리는 값을 맵핑한다.
- 그리고 각각 state를 할당한다.
- state가 사용되어지는 곳에 프로퍼티의 값을 입력해주면 해당 값이 true일때만 emailState.isVaild 를 반환한다.
// 구조분해할당으로 useReducer 와 useEffect를 함께 사용할때 최적화 방법
const { isVaild: emailIsValid } = emailState;
const { isVaild: passwordIsValid } = passwordState;
useEffect(() => {
const identifier = setTimeout(() => {
console.log("Checking form validity!");
setFormIsValid(emailIsValid && passwordIsValid); // isVaild의 value
}, 500);
return () => {
console.log("CLEANUP");
clearTimeout(identifier);
};
}, [emailIsValid, passwordIsValid]); // isVaild의 value
기존에는 유효성 검사를 통과해도 계속 콘솔 출력이 되었지만, 이 방법으로 최적화를 하면
유효성검사가 이루어져 true 일때만 useEffact의 의존성 배열이 업데이트 되기 때문에 불필요한 트래픽을 줄일 수 있다.