내가 구현하려고 하는 것은... 로그인이 성공되면 상단바의 아이콘이 사람 모양으로 바뀌어지고, 로그인을 하지 않으면 상단바의 아이콘이 LOGIN / SIGNUP 으로 나타내는 것을 구현하는 것이다.
그래서 내 생각에는 상단바 컴포넌트에서 isToken 이라는 useState 변수를 선언하여,
useEffect 를 사용해 만약 isToken 이 true 이면 아이콘이 사람 모양, isToken 이 false 이면 아이콘이 LOGIN / SIGNUP 으로 바꾸도록 코드를 짰었다. (이 모든건 상단바 컴포넌트 안에서 짬)
그런데 멘토님이 조언을 해주었다.
로그인 컴포넌트가 업데이트 된다고 해서 상단바 컴포넌트가 업데이트가 되는 것이 아니다.
그러면 어떻게 하는지 도움을 여쭤봤다. 멘토님 왈.....
props 를 생각해볼 수 있기는 하지만... 사실
token 을 전역 상태에서 관리하는 것이 낫다
왜냐하면 상단바와 login 은 형제관계라 props 로 넘겨주는건 개념상 맞지 않다.
그래서 라우터에서 상단에 위치를 시켜줘야 상단바와 로그인이 자식이 되서 더 좋은 관계가 된다. 사실 이런 원리는 리덕스? 컨덱스트 api 에서 이런 state 변수를 상단에 위치시켜줘서 전역적으로 관리하는 방법에 대해서 배우게 된다.
그래서 나는 아래처럼 작성해주었다.
그러나 login.js 파일에서 내가 짠 useEffect 는 랜더링될때마다 실행되기 때문에 좋지 않다고 한다.
useEffect(() => {
setIsToken(!!localStorage.getItem('access_token') ? true : false);
}); // useEffect 는 랜더링 될 때 마다 실행되기 때문에 좋지 않음
// 로그인 딱 성공될 때 한번 실행하기
// fetch .then .then 에서 써주기
따라서 다음과 같이 login.js 파일 코드 사이에 써주었다.
const handleButtonValid = () => {
if (!getIsActive) {
alert('please write a password or email address');
} else {
fetch(API.LOG_IN, {
method: 'POST',
body: JSON.stringify({
email: inputValue.userEmail,
password: inputValue.userPassword,
}),
})
.then(response => response.json())
.then(result => {
if (result.message === 'success') {
localStorage.setItem('access_token', result.token);
setIsToken(true); // 여기에 작성
navigate('/');
} else {
alert('잘못된 정보입니다!');
}
});
}
};
이러면 로그인이 성공될 때 한 번만 랜더링 되기 때문에 효율적인 코드가 된다.
오늘로써 배운 것은 어떤 컴포넌트가 랜더링된다고 해서 다른 컴포넌트는 랜더링되지 않는다는 것이다.
여기서 리액트의 특성에 대해서 다시 한번 배우게 되었다. 실수를 한번 함으로써 좀 더 크고 유익한 배움의 결과물을 얻는 것 같다. 그러니까 실수 하는 것을 두려워 하지 말자!
'💎 React' 카테고리의 다른 글
동적 라우팅 - Path Parameter 와 useParams (0) | 2021.12.19 |
---|---|
styled-components (0) | 2021.12.13 |
리액트 204 에러 (0) | 2021.12.08 |
장바구니 창 조절 (0) | 2021.12.03 |
상수데이터, 목데이터 (0) | 2021.12.01 |