마이페이지 트러블 슈팅 과정
제발 그만 나와~!
들어가며😃
프로젝트를 진행하며 가장 어려었던 부분은 마이페이지였다. 요구사항이 계속 디벨롭되어 기존 로직이 변경되어 개발해야할 컴포넌트가 갑자기 많아지기도 했고, 그 과정에서 한 컴포넌트 당 최소 세개의 이슈는 만났던 것 같다.. 그만큼 아픈 성장통을 주었던 마이페이지 녀석,,🥲🥲🥲 오늘은 발생했던 이슈들에 대해 정리하고 어떻게 문제를 해결했지 기록해보려한다.
아래는 내가 만났던 이슈 리스트이다.
마이페이지
필터링 메뉴 유지 현상
: 공통컴포넌트를 사용하며 게시물의 카테고리를 변경해주는 메뉴가 다른 컴포넌트로 넘어가도 선택되었던 메뉴로 유지되어 강제 필터링 현상데이터 패치 오류
: 프로필 수정 후 다시 마이페이지로 라우팅 되었을 때 데이터가 바로 반영안되는 현상데이터 캐싱
: 탭 메뉴가 변경됨에 따라 카드 컴포넌트 변경되지만 좋아요 정보를 담고 있는 하트 버튼에 데이터가 캐싱되어 실제 데이터 값과 상이한 현상탭 초기화 현상
: 마이페이지 내에서 게시물 페이지 이동 후 다시 마이페이지로 돌아왔을 때, 탭이 디폴트 값인 프로필로 계속 초기화 되는 현상
마이페이지 수정
폼 데이터 전달 값
: 인풋창에 Default Value 값을 보여주고 있지만, 인풋창을 건드리지 않으면 빈값으로 인식하여 오류메시지 발생변경된 데이터만 전달
: 변경된 이외의 값들은 null값이 되어 값을 아예 지워버림빈값 전달 시 반영 안됨
: 위의 문제를 해결하기 위해 백앤드에서 null 처리를 하였지만 이 부분으로 인해 실제 빈값을 보내면 값을 지워버리는 사이드 이펙트 발생이미지 전송 안됨
: 이미지 변경 로직에 정상적으로 데이터를 보내고 DB에 데이터가 쌓인 것을 확인했지만 실제로 반영안되는 현상기본 이미지 설정
: 유저가 아바타 이미지를 기본이미지로 다시 되돌리고 싶을 때, Form 데이터에 null 값을 주면 통신 실패
이 외의 자잘한 오류들이 많지만 나를 가장 힘들게 했던 녀석들이고 오늘은 몇가지만 추려 정리해보겠다.
탭 초기화 현상 - useEffect, SessionStorage
위는 등록게시물 탭의 게시물에 들어갔다가 뒤로가기를 누르면 탭이 프로필로 초기화 되는 현상이다. 마이페이지 내에서도 지원관리 등의 목적으로 페이지를 오고가는 경우가 많을 건데 히스토리가 리셋되는 현상이 문제가 있다고 생각했다. 이를 해결하기 위해 유저가 탭을 누를때마다 어딘가에 정보를 저장해야했고, 일시적인 정보의 특성에 맞게 LocalStorage 보단 SessionStorage를 저장고로 선택했다.
해결 코드
// 마이페이지 탭을 초기화 시키는 원인이였던 기존 코드
const [activeTab, setActiveTab] = useState("profile");
// 마이페이지에 등록된 게시물에서 뒤로가기를 눌렀을 때 탭이 유지되도록 설정
useEffect(() => {
const savedActiveTab = window.sessionStorage.getItem("activeTab");
if (savedActiveTab) setActiveTab(savedActiveTab);
}, []);
사이드 이펙트 및 해결 코드
위의 코드를 추가 시켜 마이페이지 내에서는 탭이 유지가 잘 되는 것을 확인했다. 그런데…헉😲 네비 바를 통해 랜딩페이지, 다른 게시판에 들어갔다가 다시 마이페이지에 오면 세션에 저장되어있는 정보때문에 리셋되어야할 페이지가 이번엔 리셋되지 못하는 사이드 이펙트가 발생하였다.
이를 해결하기 위해 탭으로 이동할 수 있는 3가지 페이지에 아래의 코드를 추가시켜 sessionStorage 데이터를 삭제해주었다. 문제해결 완료🙆🏻♀️
window.sessionStorage.removeItem("activeTab");
필터링 메뉴 유지 현상 - useEffect
관심게시물과 등록게시물 탭에 할당되는 데이터들의 성격이 비슷하여 같은 컴포넌트 내에서 데이터만 분리해주었다. 그러다 보니 좌측 탭을 이동할 때, 우측 필터링 메뉴가 유지되는 현상이 나타났다. 이를 해결하기 위해 아래와 같은 코드를 추가해주었다.
해결코드
// 기존 코드
const [filterMenu, setFilterMenu] = useState("all");
const onClickFilterMenu = (type: string) => () => {
if (type === "projects") setFilterMenu("projects");
else if (type === "recruits") setFilterMenu("recruits");
else setFilterMenu("all");
};
// 필터링 메뉴 초기화를 위한 추가 코드
useEffect(() => {
setFilterMenu("all");
}, [activeTab]);
단순한 로직 하나 추가해줬을 뿐인데 마음이 참 편안해졌다.
폼 데이터 전달 값 - useEffect
마이페이지 수정 페이지의 구조는 데이터를 받아와 input 창에 defaultValue 로 보여지는 부분이 많다. 닉네임을 제외한 부분들은 useState를 통해 관리되므로 어떠한 변경 사항이 없다면 기존 데이터를 할당한다. 하지만 form 데이터를 사용해 데이터를 전달하는 닉네임은 인풋창에 어떠한 변경사항이 없다면 그냥 빈값으로 인식해버려 form 데이터의 유효성 검사에 걸리게 되는 이슈가 발생한다. 이 문제를 해결하기 위해 정말 많은 고민을 했다.
닉네임을 다시 useState로 관리하기엔 유효성 검사에 대한 로직을 다시 적용해주어야하고 전달해주어야할 props값이 길어지는 등의 다양한 문제를 고려해야했다.
그리고 번뜩 떠오른 아이디어⚡️ 페이지가 랜더링 되었을때 인풋창에 커서를 위치시킨다면??
해결 코드
useEffect(() => {
const inputElement = document.querySelector < HTMLInputElement > "#nickname";
if (inputElement) {
inputElement.focus();
}
}, []);
문제 해결책은 고민한 시간에 비해 매우 단순한 로직으로 구현되었다. 사실 매우 다행인 부분이다. 이렇게 간단하게 문제를 해결할 수 있었다니🥹 인풋창에 커서가 바로 할당되면서 defaultValue 값이 바로 value 값으로 할당되서 정상적으로 값을 보낼 수 있었다.
회고😃
위에서 다루지 못한 이슈들 중에 백앤드와 소통해야만 해결할 수 있는 이슈들이 있었다. 처음에는 데이터 처리 로직을 서로 알지 못했을때 마주한 이슈는 모두 내가 잘못해서 발생한 줄 알았고, 아무리 원인을 찾아보려해도 전달하는 상태값과 통신 상태는 정상이라 이해가 되지 않아 백앤드 분께 상황을 설명하고 물어봤다. 그리고 나서는 프론트에서만 해결할 수 있는 문제가 아니였다는 것을 깨달았고, 데이터를 다루는 로직에서는 백앤드분과 정말 많은 소통이 필요하다는것을 몸소 체험했다.
아바타 이미지를 다루는 문제에서는 실시간으로 화면을 공유하며 며칠간 해결되지 않는 문제에 모두 몰입했고 다양한 해결책을 만들고 시도했었다. 그리고 api를 수정하거나 새로 만들거나 등의 반복 작업이 있었다. 아바타 이외의 프로필 수정 부분에서는 null 값 처리에 대한 의견을 많이 나누었다. 데이터 낭비를 줄이기 위해 변경된 데이터만 보냈지만 백앤드 쪽에서는 null 값을 없는 값으로 인식하였고, 이 문제를 해결하니 실제로 들어온 빈값에 대해서는 값을 반영하지 않는 사이드 이펙트가 발생했다. 이는 ‘’ 또는 [] 과 같은 비어있는 값을 모두 null 처리를 하여 일어나는 문제였다.
이런식으로 문제를 마주하고, 원인을 알아내고, 해결하는 과정이 꽤 재밌었다. 나는 정말 이 한번의 프로젝트로 많은 것을 배웠다. 개발 자체에 대한 것도 많이 배웠지만 협업에 대한 부분을 많이 배운 것 같다. 적극적으로 문제를 해결하려는 나의 태도, 문제의 원인을 알아내는 방식, 문제를 공유하는 방식 다양한 방면에서 많이 성장한 것 같다. 앞으로의 프로젝트에서는 어떤 성장을 할지 참 기대가 되는 부분이다.😀