Side effects
- 어떤 함수가 실행됨으로써 화면의 변화가 일어나는 것
React Component는 Props와 State가 변경될 경우, Component를 재 실행해 화면을 다시 그린다.
=> Side Effect
비동기 통신 또는 이벤트에 의해 Props혹은 State가 변경될 경우 Component를 무한히 재실행하는 부작용이 생길 수 있다.
REST API를 이용해 응답을 받아와 State에 할당해보기
에러가 발생하는 원인
State / Props가 변경되면 해당 컴포넌트는 항상 재실행 된다.
무한반복 에러 해결 방법
- 특별한 상황일 때 만 state가 변경되도록 한다.
컴포넌트가 처음 실행되면 fetch해, state를 변경한다.
useEffect 를 사용해주면 무한반복을 멈출 수 있다.
import { useRef, useEffect } from "react";
export default function Header({ token, setToken }) {
const emailRef = useRef();
const passwordRef = useRef();
// 이 컴포넌트가 실행되자마자 Local Storage에 token 값이 있는지 확인한다.
// Token 값이 있다면 token state에 값을 할당.
useEffect(() => {
const storedToken = localStorage.getItem("token");
if (storedToken) {
setToken(storedToken);
}
}, [setToken]);
const onLoginClickHandler = async () => {
const email = emailRef.current.value;
const password = passwordRef.current.value;
if (!email) {
alert("Email을 입력하세요.");
emailRef.current.focus();
return;
}
if (!passwordRef) {
alert("비밀번호를 입력하세요.");
passwordRef.current.focus();
return;
}
const response = await fetch("http://localhost:8080/auth/token", {
method: "POST",
body: JSON.stringify({ email, password }),
headers: { "Content-Type": "application/json" },
});
const json = await response.json();
setToken(json.token);
// token의 값을 브라우저의 로컬 스토리지에 작성한다.
localStorage.setItem("token", json.token);
// token의 값을 브라우저의 세션 스토리지에 작성한다. (같음)
// sessionStorage.setItem("token", json.token);
};
return (
<header>
{token && <div>로그인이 완료되었습니다.</div>}
{!token && (
<div>
<label htmlFor="email">EMAIL</label>
<input type="email" id="email" placeholder="Email" ref={emailRef} />
<label htmlFor="password">PASSWORD</label>
<input
type="password"
id="password"
placeholder="Password"
ref={passwordRef}
/>
<button onClick={onLoginClickHandler}>로그인</button>
</div>
)}
</header>
);
}