항해/항해99

(WIL)weekly I learned 04 4주차 회고록

youngble 2021. 11. 28. 23:21

 

숙련주차인 4주차를 거치면서 우리가 배우는 함수형 컴포넌트로 사용하는것에 대해서 어느정도 익숙해진것같다.

그안에서 기존에 배웠던 클래스방식의 라이프사이클이 어떻게 이루워지는지 알게되었고 왜 클래스방식보단 함수형태로 쓰는지 알게되었다.  클래스로 쓸때는 자바스크립트의 지식도 많이 요구되어서 this 바인딩이나, 클로져, state의 흐름등도 알아야하고 제약이 많이있었다.

하지만 함수형 컴포넌트를 쓰면서 이러한 클래스의 기능등을 리액트 훅을 써서 간단하고 짧지만 모든 기능을 할수있게 해주는게 편하다고 생각했다. 

 

요번주차때 가장 집중하고 또 이해하는데 시간을 많이 투자한건 역시 redux의 구조와 어떤 흐름으로 이루어지는지, 그리고 Redux의 휘발성 데이터를 유지하기위해 파이어베이스 스토어를 사용할때 어떻게 이 파이어베이스 서버와 통신을 할수있는지였다.

이틀동안 리덕스와 파이어베이스 이론과 코딩 구조를 임민영 튜터님 강의를 들으면서 잡았고, 두번째보면서 큰틀과 각 코드들의 의미를 알게되면서 프로젝트를 진행하였다.  지난주차보다 확실히 리덕스와 파이어스토어 장점으로 인해서 요구하는 프로젝트 CRUD를 구현하는데 시간이 덜 들어서 요구사항인 CREATE부분은 하루만에 완성하였고, 나머지 RUD 부분은 목요일날 끝낼수있었다. 이때 CRUD를 구현하기위해 여러가지를 배웠는데 async await 이 서버통신과 비동기처리하기위해 데이터를 받아오기까지 다른랜더링을 하고 데이터가오면 그때 쓰게 하는 원리를 좀더 알게되었던거 같다. 이때 비동기처리를 알려면 콜백함수도 알아야하고, then , 콜백 지옥, Promise 등 추가로 왜 async await 이 생기게 되었는지도 찾아보게되었다. 깊이가 좀고 많아서 나중에 좀더 집중해서 배우기로하고 기본적인 개념만 잡았다..

 

요번주차는 술술 쓸수있는 구간이 아닌 어떻게 쓰는지 숙련과정이라고 했는데 그런거같다. 사용할줄알고 원리도 알고 각각 코드의 의미를 알지만 직접 내가 술술술술 막힘없이 자신은 없다. 계속 코드를  재활용하면서 코드를 복기하면서 다시 머리에 넣고 쓰고 하다보면 나중엔 정말 숨쉬듯이 쓸수있지 않을까 생각을 했다

 

개인프로젝트 완성화면

기능: CRUD

Create

1. 추가하기 버튼을 오른쪽 아래 고정하여 스크롤을 내려도 위치가 변하지 않게 display:fixed 를 해줌

2. 클릭시 add할수있는 컴포넌트페이지로 이동

3. 3개의 input 박스를 만들어주고 각각 Ref 를 주어 입력값 저장

4. 추가하기 버튼과 뒤로가기 버튼을 만들고, 추가하기버튼을 눌르면 alert 창이 뜨고 저장이 되고 기존에 적었던 input값들을 clear 시켜줌. 뒤로가기로 하면 원래 메인화면으로 넘어감. 

 

Update

1. 메인화면에서 추가된 단어장 오른쪽 상단에 연필모양을 눌러 수정하기 페이지 컴포넌트로 이동하게 해주었고,

이동한후에 그 단어장에 있던 값들을 가져오기위해서 useParams 로 그 페이지로 이동시에 index값을 담게 하였고, 그것을 useSelector로 가져온 리스트에 [index]식으로 붙여서 input 박스 속성 defaultValue에 그인덱스에 해당하는 값을 각각 추가하게함.

 

2. 수정하기를 누르면 update가 되는데 이때 리듀서의 update 케이스 부분에서 map 함수로 새로운 list를 만들때 수정하려고 받은 데이터 인덱스부분과 map 인덱스와 같으면 그인덱스 부분에 해당하는 배열객체 순서에  데이터를  넣어주고 그외엔 기존의 state 값들을 넣어줌. 그렇게 map함수를 통해 만들어진 새로운 list 변수를 return 에서 list 키 객체 값으로담아줌

 

Delete

메인화면에서 해당 단어장의 오른쪽상단의 휴지통 모양을 눌르면 해당하는 단어장의 정보를 dispatch 하여서 리듀서부분에서 filter를 이용하여 해당하는 값은 제외하고 새로운 리스트 배열을 만들어주게했다.

 

Read

이렇게 파이어스토어 저장된 값들을 불러와서 화면에 뿌려줘야하기때문에 초반처음에 한번 랜더링하기위해서 useEffect에서 Didmount 부분에 Load 리듀서를 거치기위한 dispatch를 넣어주었다. 

그리고 그 dispatch 과정에서 현재 파이어베이스가 가지고있는 값을 doccollection 을 이용하여 가져온 리스트를 sort를 이용하여 정렬하여 return 하게 해주었다. 

 

Problem 과 해결과정

1. 단어장 카드의 순서 랜덤

 

요번주차때 막혔던 부분은 단어를 추가하면 리덕스에 쌓이는것과 파이어스토어에 쌓이는 리스트 배열정리다르게 이루워져서 다시 Load 했을때 웹브라우저화면에서 보여주는 순서가 바뀌어버렸다.

더 디테일하게 이야기하면 내가 준 데이터 문서객체를 파이어스토어에 저장하게되면 파이어스토어에선 이 받아온 객체에 고유의 id 를 a-zA-Z0-9 형식으로 랜덤하게 부여하게 설정되는데, 순서를 정리할때는 이름맨앞글자로 정리가된다.  따라서 map()함수를 이용하여 단어장 리스트 값을 불러오면 인덱스대로 불러오기때문에 달라지기때문이다.

어떻게 풀수있을까 생각해보았고 먼저 파이어스토어에서 이러한 랜덤하게 id 주는걸 순서를 붙여서 줄순 없을까 찾아봤지만 그런건 없었고, 멘토분들께 질문을 해서 알게된건 파이어베이스의 공식 문서를 통해 firebase의 내장함수를 사용하여 정렬하는 방법 과 서버가 업데이트를 수신하는 시기를 추적하는 타임스탬프를 적용하는 방법을 써보는걸 추천해주셨다. 근데 아무리봐도 생소하고 실질적으로 내 코드로 쓰기 어려워서, 그 기본 핵심포인트만 생각해서 다른 방법을 쓰기로했다.

그때 이용한거 sort 로 load하는 부분에서 load 할 데이터 리스트를 넘겨주기전에 sort 로 정렬할것, 근데 그 정렬 방식이 카드가 추가한 순서대로 되야하므로 카드에게 고유의 값을 줄것 이였다. 그 고유의 값을 처음엔 인덱스로 줄려고했다 추가만 하고 수정만 한다면 아무문제없지만 삭제기능을 쓰게되면 인덱스순서가 꼬이게되서 버그가 생긴다. 그래서 어떤 고유의 값을 줄까 생각하다가 Date() 함수를 쓰면 어떨까 생각을했고 밀리세컨 단위로 계속 누적된 날짜값을 주기로했다.

이때 쓴건 Date.now() 였다. 이렇게 되면 어떤 단어장을 지우더래도 인덱스로 넘겨준게 아니고 시간이 누적된 값으로 지정해주었기때문에 순서가 꼬일일이없었다. 따라서 이 값을 기준으로 sort 에서 a.data -b.data 로 정렬해주었다. 

 

2. useEffect 부분에서 단어장이 수정되거나 삭제되거나 추가될때 리랜더링이 이뤄지게 하기위해서 DidUpdate 가 이뤄지게 할때 2번째 인자에 넣을 값이 무엇인지 몰랐고 계속 그래서 그냥 list 값을 넣어주면 무한루프가 걸리게 되었는데 이는 값이 같더래도 기존 데이터의 ref 값과 리듀서를 거쳐서 새로 만들어지는 ref 값이 다르기때문에 다른것으로 인식하여 무한 루프가 되는걸로 판단하였고, 이를 막기위해서 list 를 주지않고 length 로 주어서 length가 바뀔때만 update 가 이뤄지게 해주었다.