지난번에 useAxios 커스텀 훅을 만들어 네트워크 통신 후 response를 받아오도록 만들고, 네트워크 통신과 관련된 코드는 도메인 별로 나누어 API 문서화를 진행하였다.
이제는 이 useAxios 커스텀 훅과 네트워크 통신 코드를 사용하여 데이터가 바뀌었을 때, 바뀐 데이터를 컴포넌트에 실시간으로 적용을 시켜주어야하는 과정이 필요하다. 이 방식을 알아내기 위해 관련된 블로그를 몇날 몇일을 붙잡고 기본적인 로직의 처리 과정에 대해 이해하려고 노력했다. 노력끝에 정답을 발견하였을 때 정말 유레카를 외칠 뻔했다~ 설날이였는데 설 연휴 내내 이 문제를 해결하기 위해 노트북만 붙들고 있었던 것 같다. 해결방법 발견 후에 글로 정리하여 디스코드에 올려 프로젝트 팀원분들께 공유드렸다. 팀원분들도 결과적으로 해당 방법을 사용하여 실시간 업데이트를 잘 적용시켰다고 하셔서 다행이다.
나는 Post 작성, Comment 작성, Post '좋아요' 누르기 기능, 타 유저 팔로우/언팔로우 기능 등등 데이터가 변하는 상황이 정말 많은 컴포넌트를 맡아 프로젝트를 마무리하고 제출하는 날까지 정말 수정과 수정을 거듭하였다... 내가 더 이 로직에 목 매달 수 밖에 없었던 이유^^
꾸준히 테스트하고 백엔드 개발자분들과 소통하면서 최대한 서버에 요청을 덜 하면서(트래픽 과열 방지) 실시간 업데이트가 정상적으로 이루어질 수 있도록 최대한 머리를 굴리고 굴려보았다 ㅋㅋㅋㅋ 눈물난다 눈물나~ 맛피팀~디버깅을 좋아하신다고 하셨던 백엔드 개발자님도 함께 서버 요청을 봐주시면서 계속 새벽 밤을 새주셨다... 계속 재밌는 얘기도 해주셔서 더 힘내서 할 수 있었던 것 같다. 티키타카 베뤼굿~!
거두절미하고 커스텀 훅을 사용해 데이터 리로딩하는 과정을 기록해보자. 레츠기릿.
이전에 사용하던 API 요청 처리 완료된 후 다시 한번 GET 요청을 보내는 방식에는 문제점이 있었다. 데이터 리 로딩 후 페이지 이동이 없을 때만 정상 작동하고 이동한 페이지에서는 이전의 데이터가 보인다는 것이였다. 예를 들어, 특정 맛포스트 모달의 좋아요 수가 하나 올라간 후 모달이 닫히고 메인 페이지가 보일 때 그 맛포스트의 썸네일 이미지를 호버하면 좋아요 수가 +1 된 상태가 보여야 정상인데, 그렇지 않았다는 것이다. 즉 어디에선 실시간으로 업데이트되고 어디선 안되는(?) 불안정한 모습을 나타냈던 것이다.
"아, 내가 원하는 타이밍에 데이터가 리로딩됐음 좋겠다. 데이터 리로딩의 트리거가 될만한 무언가가 있어서 모달에서 데이터가 업데이트 됐을 때 메인페이지에게 데이터가 업데이트 됐으니 너도 새로운 데이터를 받아서 뿌려줘~ 라고 말해줄 수 있는 수단이 있으면 어떨까?"
네트워크 통신 커스텀 훅을 만들기 위해 참고했던 코드를 면밀히 살펴보았다. 내가 이전에 배웠던 useFetch 코드와 다른 점이 있었다. 그건 바로 API 요청을 보낼 시점을 정할 수 있는 불린 변수가 있었던 것이다. 옳다구나. 이 변수를 가지고 지지고볶아야 겠다.
이 변수를 사용하여 내가 원하는 타이밍에 데이터가 업데이트 될 수 있도록, 특정 페이지 또는 모달에서 데이터가 업데이트 됐을 때 그걸 다른 페이지에도 알려줄 수 있도록 만들어보자.
useAxios를 사용하여 컴포넌트를 실시간 업데이트 하는 로직
1. boolean 값을 가지는 상태를 하나 만들고, 해당 boolean 값이 바뀌도록 하는 핸들러 함수를 생성한다.
2. 데이터 값의 변경을 핸들링하는 로직에 만든 핸들러 함수를 추가하여, 데이터의 값이 변경되면 1에서 만든 상태 값이 바뀌도록 만들어준다.
3.useAxios의 종속성 배열에 1에서 선언한 상태 값을 넣어 상태값 변경 시 axiosData 함수가 실행되어, callback 함수인 네트워크 통신 함수가 실행되며 response data가 바뀌어 실시간으로 업데이트 된 데이터를 볼 수 있도록 한다.
해당 로직을 바탕으로 유저가 특정 Post를 클릭해 모달 컴포넌트를 통해 Post 게시글을 조회한 뒤, '좋아요'를 누르고 모달을 끄고 도메인 페이지로 돌아오면, 해당 Post의 Likes 수가 1이 증가된 값으로 업데이트 되도록 만들어보자.
먼저 특정 Post의 Likes 값이 변하면 도메인 페이지가 리렌더링되어야 하므로 도메인 컴포넌트에 상태를 하나 만들고, 해당 상태 값을 변화시키는 핸들링 함수도 만든다. 도메인페이지에서는 모든 포스트가 reload 되어야하므로 함수 이름을 getAllPostsReload로 하였다.
const [postsReload, setPostsReload] = useState<boolean>(false);
const getAllPostsReload = () => {
setPostsReload(!postsReload);
};
이 함수를 자식 컴포넌트에 Props로 내려주어 자식 컴포넌트 내 Likes 수를 변하게 만드는 로직 하단 또는 백드롭이 클릭되어 모달이 꺼지게 만드는 로직 하단에 추가하여 변화가 일어났을 때 함수가 실행되도록 한다.
모달이 꺼지도록 하는 토글 함수 내에 추가해주자.
const onClickToggleModal_BD = useCallback(() => {
getAllPostsReload();
setOpenModal(!isOpenModal);
}, [isOpenModal]);
getPosts 함수는 Post의 list를 가져오는 네트워크 통신 함수이다. 이 함수가 콜백함수가 된다. 이제 종속성 배열에 상태값을 넣어 상태 값이 변경되면 데이터를 다시 get해 새로운 데이터가 출력되도록 한다.
const { responseData: posts } = useAxios(getPosts, [postsReload], false);
이렇게 하면 Likes 수가 변동될 때마다 리렌더링이 되어 새로고침 없이 실시간 업데이트된 데이터를 볼 수 있다.
useAxios 커스텀 훅을 사용하기 전에는 모든 처리가 종료된 후 다시 한번 GET 요청을 보내 업데이트 된 데이터를 가져오거나 useEffect 내에서 GET 요청을 보내 컴포넌트가 리렌더링 되도록 하는 등의 방식을 사용하여 이를 처리했었다. 처음엔 코드 추상화에 대한 개념이 익숙치 않아 useAxios 커스텀 훅 로직 이해 및 적용에 시간이 소요되었지만, 차근차근 이해하고 프로젝트에 적용하고 보니 코드 재사용성을 높일 수 있던 아주 효율적인 방법이라는 생각이 들었다. 이래서 관심사 분리, API 문서화를 해야하는 구나!
프로젝트 제출 일주일 반 정도를 남기고 진행한 리팩토링이여서 더 마음이 급하고 불안했었는데 결과적으로 팀원 분들에게도 이 방법이 잘 전달되어 프로젝트의 전체적인 리팩토링이 잘 된 것 같아 다행이다.
내 설 연휴를 바쳤다. 프로젝트에 가장 시간을 많이 쏟은 부분... 그래도 열심히 해서 팀에 큰 도움이 된 것 같아 아주 뿌듯한 연휴였다. 이전에 연구원으로 잠깐 근무했을 때의 습관이 있어서 그런가 의자에 엉덩이 붙히고 오래 앉아있는 것에 매우 익숙해서 그나마 다행인 것 같다. 끈기 하나는 끝내주지 또^^(근거 있는...자신감)
이거 나 아냐? 맨날 엉덩이 붙히고 눈 게슴츠레 뜨고 노트북 보는 애...
'코드스테이츠 SEB FE 41기 > Main-Project(MatP)' 카테고리의 다른 글
[회고] Main project '맛P' 회고 (1) | 2023.02.01 |
---|---|
[react] 프로필 이미지 변경하기(feat. typescript) (0) | 2023.01.31 |
[react & typescript] MUI Popover 사용기(Delete confirm 기능) (0) | 2023.01.31 |
[react] 간단히 star rating chart 구현하기(feat. typeScript) (0) | 2023.01.25 |
[react] star-rating 구현하기 2탄(이번엔 소수점까지!) (0) | 2023.01.25 |