Today I Learned
- 팀 프로젝트 진행
팀 프로젝트 진행 기록
로그인한 유저가 누구인지 어떻게 알 수 있지?
머리 감다가 갑자기 누가 로그인했는지 어떻게 특정할 수 있는지 궁금해졌다. 로그인 페이지에서는 input에 입력한 값으로 아이디와 비밀번호를 DB에서 조회해서 find()로 찾아낸다. 그런데 로그인 페이지를 벗어났을 때는 지금 로그인한 게 누구인지 어떻게 알 수 있을까? 만약에 마이페이지에 현재 로그인한 유저의 아이디를 보여준다고 할 때 find()를 어떤 값과 대조해서 가져와야 하는 걸까?
검색하다 보니 로그인한 유저의 정보를 로컬스토리지 혹은 세션스토리지에 저장해야 하는 거 같다. 나는 로컬스토리지를 사용하기로 했기 때문에 로컬스토리지에 대해서 더 알아보기로 했다.
localStorage 사용 방법
// 데이터 저장하기
localStorage.setItem("key", value);
// 데이터 읽기
localStorage.getItem("key");
// 데이터 삭제
localStorage.removeItem("key");
// 모든 데이터 삭제
localStorage.clear();
// 저장된 키/값 쌍의 개수
localStorage.length;
localStorage는 sessionStorage와 비슷하지만, localStorage의 데이터는 만료되지 않고 sessionStorage의 데이터는 페이지 세션이 끝날 때, 즉 페이지를 닫을 때 사라진다는 점이 다르다. 따라서 자신의 브라우저에서 데이터를 계속 보존시키면서 사용한다면 localStorage를, 여러 페이지 마다 다른 데이터를 보존시키고 싶다면 sessionStorage를 사용하면 된다.
유의해야 할 점은 localStorage를 사용할 때 유지되는 데이터는 자신의 컴퓨터, 자신의 브라우저에만 저장되어 있고 동일한 링크의 다른 컴퓨터에는 당연히 데이터가 저장되어 있지 않다는 것이다. 자신의 브라우저의 데이터가 자신의 localStorage에 남는다는 것을 기억하도록 하자!
참고
https://developer.mozilla.org/ko/docs/Web/API/Window/localStorage
https://velog.io/@choco1drink/React-LocalStorage-이용한-로그인-구현
로그인 시 작동하는 loginHandler 함수 수정하기
const logInHandler = (e) => {
e.preventDefault();
// users에서 특정 유저의 userId와 userPw가 모두 일치하는지 확인한다.
const user = users.find((user) => user.userId === userId && user.userPw === userPw)
// 일치하지 않을 때
if (user === undefined) {
alert("로그인 실패")
// 모두 일치할 때
} else {
alert("로그인 성공")
const switchUser = {
id: user.id,
userId: user.userId,
userPw: user.userPw,
userName: user.userName,
isLogin: true,
}
// 로그인 성공하면 isLogin을 true로 변경함
dispatch(__switchIsLogin(switchUser))
// 로그인 성공하면 input 창 비우기
setUserId('');
setUserPw('');
}
};
기존 코드. 원래는 로그인하면 로그인한 유저의 isLogin을 true로 바꿔서 isLogin이 true인 경우에만 글 작성 권한을 준다든지 등의 방법으로 사용하려고 했었는데 이렇게만 해서는 현재 로그인한 유저의 id가 무엇인지 알 수 없기 때문에 로그인할 때 localStorage에 로그인한 유저의 id를 저장하기로 했다.
// 로그인한 특정 유저의 id를 localStorage에 저장함
// 저장하는 이유는 어느 페이지에 가든 현재 로그인한 유저의 id를 불러오기 위해서
localStorage.clear();
localStorage.setItem("id", user.id)
loginHandler 함수 안에 localStorage 관련 코드를 추가했다. [로그인] 버튼을 클릭했을 때 일단 localStoreage를 깨끗하게 비운 다음에 현재 로그인한 user의 id를 저장한다.
그럼 로그인했을 때 이렇게 local storage에 내가 로그인한 계정의 id 값이 들어가 있는 것을 확인할 수 있다. 이제 얘를 localStorage.getItem("id")를 해서 어느 페이지에 가든 현재 로그인한 유저의 id를 가져와서 이용할 수 있다.
const switchUser = {
id: user.id,
userId: user.userId,
userPw: user.userPw,
userName: user.userName,
isLogin: true,
}
// 로그인 성공하면 isLogin을 true로 변경함
dispatch(__switchIsLogin(switchUser))
원래 users의 DB 구조는 이렇게 되어있었는데 isLogin이 필요 없어지기도 했고 혹시나 쿠키 삭제 등의 이유로 localStorage에서는 로그인한 유저의 id가 삭제되었는데 isLogin은 계속 true로 남아있는 경우가 발생할까 봐 isLogin은 DB에서 삭제하기로 했다. (이렇게 되면 __switchIsLogin이라는 thunk 함수도 필요가 없어진다.)
useRef의 장점
useState를 사용하면 state가 변할 때마다 컴포넌트가 리렌더링 되면서 내부 변수들이 초기화되는데 useState 대신 useRef를 이용해서 값을 변경하면 리렌더링 되지 않고 변수들이 유지된다. 따라서 렌더링을 발생시키지 말아야 하는 값을 다룰 때 편리하다.
https://itprogramming119.tistory.com/entry/React-useRef-사용법-및-예제
회원가입 시 Form Help Text 구현하기
모든 것을 alert으로 처리하기보다는 form help text를 사용하는 게 좋을 거 같아서 일단 대략적인 css 틀을 잡아보기로 했다. 일단 각 input 하단에 form help text가 뜨게 하는 데는 성공했지만 아직 해결 못한 문자게 2개 있다.
1. 각 상황에 따라 input 창 하단에 메시지를 보여주긴 하지만 만약에 유효성 검사에서 조건을 만족하지 못하더라도 가입이 가능하다.
2. input이 value를 인식하는 게 조금 느리다. 만약에 웹페이지에서 input에 abcde를 입력하고 input의 value를 콘솔에 찍어보면 abcd가 찍힌다. 그래서 만약에 이미 가입된 아이디가 abcd인데 abcde까지 입력을 해야 '이미 등록된 아이디입니다'라는 메시지가 떠서 유효성 조건을 체크하는 데 문제가 생긴다.
DB 최신순 정렬하기
josn-server에 데이터를 추가할 때 오름차순으로 저장(최신이 가장 밑으로)되는데 이대로 데이터를 불러오면 최신글이 아래로 가기 때문에 DB를 최신순으로 정렬하고 싶었다. 그래서 방법을 찾아봤더니 axios.get을 할 때 데이터 정렬 방법을 지정할 수 있다는 것을 알게 됐다.
axios.get("http://localhost:3001/comments?_sort=createdAt&_order=DESC");
그래서 일단 게시물을 등록할 때 createdAt이라는 키를 하나 추가해서 작성 시간을 기록하도록 하고 aixos.get의 URL을 수정해 주었다. 코드를 위와 같이 작성하면 createdAt을 기준으로 내림차순 정렬을 할 수 있다.
참고 https://findmypiece.tistory.com/15
회고
아침에 씻다가 갑자기 지금 로그인한 유저가 누구인지 어떻게 알 수 있지..?라는 의문이 생겨서 해결하기 어려울까 봐 걱정했었는데 로컬스토리지를 이용해서 금방 해결할 수 있어서 다행이었다. 오늘 본격적으로 회원가입 페이지 css 틀을 잡고 form help text까지 구현했는데 코드를 수정하면서 비슷한 구조로 중복되는 코드가 많아서 이걸 커스텀 훅으로 구현할 수 있을까라는 생각을 했다. 생각만 했다 ㅎㅎ