기존에 만들던 백업 사이트는 이런식으로, 로그인하면 자신의 페이지에 데이터를 추가/수정/삭제할 수 있게 되어 있다.
이때, 이 페이지를 다른 사용자도 볼 수 있도록 공유하고자 한다. 이 페이지의 데이터 그대로 보여줄 거지만, 공유페이지일 경우 데이터를 추가하거나 수정할 수는 없어야 한다.
일단 공유 용도를 위한 페이지를 따로 만들어주었다.
라우팅에서 얘기하겠지만 공유링크는 /share/(해당유저의 uid) 형식으로 만들 것이므로 uid를 useParams로 가져온다.
메인 페이지와 동일한 컴포넌트와 스타일을 사용하지만, 중간중간 데이터를 불러와야 하는 컴포넌트들에는 isShared라는 props를 추가로 내려주어 특정 요소들의 가시 여부를 컨트롤해주고, externalUid로 params 즉 이 공유페이지 주인의 uid를 내려줄 것이다.
근데 이것도 좀 반복되는 것 같아서 먼가 리팩토링을 할 수 있을것도 같네요
쨌든 이렇게 하고 sharedmainpage의 경로를 지정해주자
:uid 형식으로 써서 동적라우팅 해준다
그리고 공유링크를 복사해줘야 하니까 프로필카드 밑에 공유버튼을 만들어주자
웹사이트 기본 주소(window.location.origin)/share/로그인된유저의uid 로 링크 문자열을 만들고, 클립보드에 복사해주면 끝
* window.location.origin : 프로토콜 - 도메인 - 포트번호까지의 기본주소
* window.location.href : 현재 주소의 전체url
버튼을 눌러서 복사된 주소로 이동하면 mainpage 대신 sharedmainpage가 보인다. (추가수정삭제 등 각종 버튼들 안 보이게 설정해주는건 알아서 ~~)
🚀 트러블 슈팅
1. 기존 컴포넌트 재사용하기
공유 용도로 컴포넌트들을 다시 만들지 않고, 조건부 렌더링으로 기존 컴포넌트를 그대로 사용했다. 그렇다면 각 컴포넌트들이 공유 페이지일 때는 위에서 받아온 props(externalUid)를 통해 데이터를 가져와야 하고, 공유페이지가 아닐 때는 현재 로그인된 사용자(파이어베이스의 auth에서 가져온 유저 정보)의 데이터를 가져와야 한다.
그럼 이걸 어떻게 구분시킬 것이냐 !!
대표로 유저데이터들의 List 컴포넌트를 통해 설명하자
일단 위에서도 봤지만 props로 bool 하나, string 하나를 받아준다.
isShared는 공유페이지인지 아닌지를 표시하며, true일 경우 삭제 버튼을 가린다던지 하는 식으로 쓴다.
externalUid는 공유페이지일 경우 부모컴포넌트에서 useParams로 내려준 uid값이다. 공유페이지가 아닐 경우 이 값은 null이다.
우선 앞서 만들었던(이전 글 참고) 커스텀훅으로 useAuth로 가져온 uid를 authUid라는 이름으로 선언해준다.
그리고 일단 uid의 초기값은 빈 문자열로 설정한다.
그리고 컴포넌트가 렌더링될 때, uid를 세팅한다.
externalUid가 있다면 externaluid로 값을 세팅한다. 즉 공유페이지라면, 해당 페이지 주인의 uid가 들어가기 되고,
그렇지 않다면 authUid값 즉 로그인 사용자의 uid 값으로 uid를 세팅한다.
세팅한 이후 useEffect를 다시 사용해, 데이터를 불러오는 함수를 실행해주면 된다.
처음에는 이걸 모두 같은 useEffect 안에 넣었는데, 호출이 비동기인지라 uid를 가져오기 전에 실행이 된다거나 해서 렌더링이 똑바로 되지 않았다. 순차적으로 수행되어야 한다면 useEffect를 여러번 써주자.
2. 프로텍트 라우팅
글 내용과는 다른 부분이긴 한데, 나누기도 뭣하니 그냥 같이...
로그인되어 있지 않을 때는 메인페이지 링크를 직접 입력해도 들어가지지 않고 로그인 화면으로 튕겨나와야 한다.
그래서 그냥 간단하게 만들었었는데, 파이어베이스에서 auth정보를 갖고오는 데 짧긴 해도 시간이 걸리긴 하다보니... 로그인된 상태에서 메인페이지를 새로고침하면 로그인으로 튕겨져 나오는 문제가 있었다. auth정보를 갖고오는 중이라서 uid가 세팅되지 않은 건데, 이걸 로그인 안 했다<로 판단해서 그렇게 되는 것 같았다.
해결을 위해 프로텍트라우터 컴포넌트에 isLoading이라는 변수를 하나 추가해줄 것이다.
근데 isLoading은 useAuth에서 auth를 다 가져왔는지 여부에 따라 달라져야 한다. 이전에 만들었던 authContext로 돌아가보자.
context에 value를 추가해주고
기존 함수에서 auth를 가져오는 과정이 끝난 이후 isLoading을 false로 세팅해주는 부분을 추가한다.
그리고 프로텍트 라우터로 돌아와서 useAuth에서 isLoading을 추가로 받아주고, isLoading이 true일 때는 로딩 컴포넌트를 따로 출력하도록 한다. 그 이후에 로그인 유저 여부를 판단해 팅길지 말지를 결정해준다.
로딩화면이 출력되었다가 로그인 여부에 따라 라우팅을 결정해주는 것을 볼 수 있을 것..
'기록' 카테고리의 다른 글
[React] Context를 사용한 전역 상태관리 (4) | 2024.12.26 |
---|---|
[React / Node.js] 네이버 밴드 로그인 인증 구현 (2) | 2024.11.04 |
[A.(에이닷)] 프로젝트 경험 그거 어떻게 쌓는 건데... 에이닷과 함께! (6) | 2024.10.11 |
[Flutter] 이미지에서 선택 영역 투명화하기 (4) | 2024.10.11 |
[A.(에이닷)] LLM과 함께하는 쉬운 글쓰기 (1) | 2024.09.30 |