Node & React basic #18

Jay·2023년 5월 19일
0

Node & React basic

목록 보기
18/21
post-thumbnail

로그아웃 기능을 만들어보고자 한다!

이건 로그아웃을 위한 페이지를 만드는 게 아니라
랜딩페이지에 로그아웃 버튼을 만드는 게 다이기 때문에 금방 끝날듯

랜딩페이지에 Log Out(<button onClick={onClickHandler}>Log Out</button>)을 만들어주고 onClickHandler는 이와 같이 작성했다.

const onClickHandler = () => {
	axios.get("api/users/logout")
  	.then((response) => {
    	if (response.data.success) {
        	alert("로그아웃되었습니다. 로그인 페이지로 돌아갑니다.");
          	navigate("/login");
        } else {
          	alert("로그아웃에 실패하였습니다.");
    });
};

물론 위에 useNavigate import했고 navigate변수도 만들어줬다.
강의를 보기 전에 if문에 response만 넣었더니, data를 가져오질 못해서 로그인이 안 되어있는데도 alert랑 navigate가 실행되는 문제가 있었다.. 점검 또 점검!

그런데 가끔 랜딩페이지로 진입시 axioserror: request failed with status code 504에러가 뜰 때가 있는데 이유를 모르겠다. 매번 발생하는 오류도 아니라서.. 🤔

어쨌든 등록한 이메일과 비밀번호로 로그인한 다음 로그아웃하는건 잘 된다. 다만 마음에 안 드는 것이 로그인이 돼있을 경우 랜딩페이지의 버튼이 LogIn으로 바뀌고 로그인 창을 띄워줬음 좋겠는데 그게 아니라 랜딩페이지에선 LogOut만 가능하다는 점이다. 물론 로그인 버튼을 하나 만들어서 로그인 창으로 가게 할 수는 있겠지만 페이지가 동적으로 로그인된 유저가 있는지 없는지를 좀 확인할 수 있었으면 좋겠는데, 다음 강의가 Authentication관련 부분이니 그 쪽에서 다루기를 바라며..

랜딩페이지에 처음에 실험용으로 이런 부분을 줬는데

여기 연결된 엔드포인트를 auth로 잘 연결하고 변수를 주면 login/logout으로 버튼에 적힌 글자를 바꿀 수는 있을 것 같다만 글자가 다가 아니라 버튼에 연결된 함수도 서로 달라야 하니 음..
아예 조건부 렌더링되는 버튼으로다가 버튼 두가지를 만들어서 해야 하나?

엔드포인트를 /api/users/auth로 바꾼 다음 response를 가져왔다. 로그인이 되어있을 시 response.data.isAuth가 true일 것이다. 왜냐하면 Auth설계시 이렇게 적었으니까:

그래서 이 상태 정보를 어떤 변수에 저장을 해야겠다는 생각을 했는데 문제는 그냥 변수에 넣어버리면 axios.get이 비동기적으로 동작하면서 반환값을 할당받기 전에 로그를 찍으면서 undefined가 될 수 있다는 점이다.

// 이렇게 하면 안된다는 소리
let isLoggedIn;

React.useEffect(() => {
  isLoggedIn = axios.get("/api/users/auth").then((res) => res.data.isAuth);
}, []);

console.log(isLoggedIn);

그래서 async/await가 필요하다.

let isLoggedIn;

React.useEffect(()=>{
	const fetchData = async () => {
    	const response = await axios.get("/api/users/auth");
      	isLoggedIn = response.data.isAuth;
    }
    fetchData();
}, [])

이러면 axios.get이 완료될 때 response가 그 값을 받고, isLoggedIn도 그 때 할당될 수가 있는데, 문제는 바깥에서 console.log(isLoggedIn)을 찍어보면 여전히 undefined가 나온다는 것이다. 왜냐하면 컴포넌트가 렌더링되는 건 useEffect내의 함수가 다 실행되기를 기다린 다음 렌더링되는게 아니기 때문에 그 전의 undefined값이 나올 수밖에 없는 것..!

이럴 때는 useState를 사용할 수밖에.

const [isLoggedIn, setIsLoggedIn] = React.useState(false);

useEffect(()=>{
	const fetchData = async () => {
    	const response = await axios.get("/api/users/auth");
      	setIsLoggedIn(response.data.isAuth);
    }
    fetchData();
}, [])

이렇게 하면 state의 특성에 따라 얘가 바뀔 때 리렌더링이 일어나기 때문에 로그인이 되어 있을 경우 response.data.isAuth는 true일 것이고 우리는 true상태의 isLoggedIn state를 볼 수 있는 것이다.

그리고 하단 버튼을 isLoggedIn 상태에 따라 조건부로 만들면 된다. 지금 만들어진 버튼은 isAuth가 true일 때 버튼이고 이벤트핸들러도 잘 걸려 있으니까 true일때만 나오도록 지정해주면 됨

이렇게 해서 잘 되고 있음!
이런 기능들을 구현하다 보니 이메일을 보내서 확인하는 등의 auth 기능이 귀찮다고만 생각했는데 많은 생각을 거듭한 끝에 나온 기능이겠구나 싶고 대단하다는 생각이 든다.
지금 내 페이지에선 가짜 이메일을 넣어도 로그인이 되거든 나도 그렇게 등록했고

profile
ㄱ이 아닌 개발자가 되고 싶은 사람

0개의 댓글