Skip to content

문제 해결

HW Lee edited this page Apr 11, 2023 · 11 revisions
  • FirebaseonAuthChangeState라는 함수로 자동 로그인을 처리할 수 있는데, onAuthChangeState로만 체크하면 처음 접속 시 정보를 받아올 때 딜레이가 생기는 문제가 있었습니다. 그래서 recoil-persist를 이용하여 로컬 스토리지에 atom 형식으로 자동 로그인 정보를 저장하였습니다. (https://github.com/firebase/firebase-js-sdk/issues/5722)

  • 코드 에디터 구현 중 처음에는 SyntaxHighlighter 컴포넌트에 contenteditable={true} 속성을 주어 코드를 작성 및 수정할 수 있게 하려고 했습니다. 그러나 하이라이팅이 실시간으로 반영되지 않았습니다. 그래서 textarea를 이용하여 텍스트 입력을 받고, 입력값을 state에 저장 후 SyntaxHighlighter 컴포넌트와 같은 위치에 겹치는 방식으로 에디터를 구현하였습니다. textareaSyntaxHighlighter는 부모 divdisplay: absolute 속성을 이용하여 겹친 후 textarea의 배경과 글씨 색을 투명화하여 커서는 보이되 하이라이팅된 글자가 비쳐 보이도록 하였습니다.

  • 하이라이터에 textarea를 겹쳐놓았기 때문에 textarea는 스크롤이 되지만 하이라이터는 스크롤이 되지 않는 문제가 있었습니다. 그래서 하이라이터 컴포넌트에 useRef 훅을 이용하여 연결한 후 scrollTop 값을 textareascrollTop과 맞춰주려고 했으나, 하이라이터 컴포넌트 안에 ref 속성이 없어서 생각처럼 되지 않았습니다. 그래서 부모 divref를 연결하고 firstElementChild로 하이라이터 컴포넌트에 접근하여 scrollTop을 맞추는 방법으로 해결하였습니다. (https://stackoverflow.com/questions/56484686/how-do-i-avoid-function-components-cannot-be-given-refs-when-using-react-route)

  • 코드 카드 컴포넌트에서 설명 부분이 여러 줄일 때 마지막 줄에만 말줄임표를 나타나게 하고 싶어서 방법을 검색하였는데, 웹킷에 line-clamp라는 설정이 있어서 그를 이용하여 구현하였습니다. (https://css-tricks.com/line-clampin/)

  • 코드 에디터에서 tab 키를 누르면 포커스 이동이 아니라 들여쓰기가 되게 하고 싶었습니다. event.preventDefault() 를 사용하여 포커스 이동은 막았으나 들여쓰기는 추가 구현이 필요했습니다. 단순히 textarea의 현재 값에 ”\t”를 더하는 것은 먹히지 않았습니다. 검색을 해보니 selectionStartselectionEnd라는 속성을 이용하여 들여쓰기를 구현하는 방법이 있었습니다. 둘 다 처음 보는 속성이었는데 공부할 수 있는 기회가 되었습니다. 그러나 들여쓰기가 생각한 대로 되지 않았고 코드의 중간에서 tab 키를 누를 시 커서 위치도 올바르게 나오지 않았습니다. 그러다 setRangeText라는 속성을 발견하였고, 그를 이용하여 해결하게 되었습니다. (https://developer.mozilla.org/en-US/docs/Web/API/HTMLInputElement/setRangeText)

  • 로딩 컴포넌트를 react-queryisLoading을 사용해서 컴포넌트 개별적으로 적용했었는데, useIsFetching 훅을 이용하여 페칭 중일 때 전역으로 적용되게 변경하였습니다. 그러나 useIsFetching의 기본값이 isFetching이었기 때문에 캐싱된 데이터를 보여줄 때도 로딩 컴포넌트가 보이는 문제가 있었습니다. 그래서 useIsFetchingpredicate옵션을 주었더니 isLoading과 같은 효과를 낼 수 있었습니다.

  • styled-componentsprops를 넘겨줄 때 파스칼 케이스의 경우에 오류가 떴는데, 에러 메시지에서 제시한 대로 props의 이름을 모두 소문자로 바꾸는 방법도 있긴 했으나 표기법을 통일하고 싶기도 했고 최신이자 깔끔한 방법인 transient props 방법을 사용하기로 하였습니다. props명 앞에 $를 붙여 styled-components에 넘길 props인지 리액트가 분석할 프로퍼티인지 구별하게 하는 방법입니다. (https://styled-components.com/docs/api#transient-props)

  • 코드 작성, 수정 시 페이지를 벗어나려 하면 react-router-domuseHistory 훅을 사용하여 confirm 창을 띄우려 했지만 v5 때에는 있던 useHistory 훅이 v6으로 업그레이드되면서 사라져서 다른 방법으로 구현하려고 하는 중입니다. (https://github.com/remix-run/react-router/issues/8139)

  • 메인 페이지에서 Out of memory 오류가 뜨면서 브라우저가 죽어버리는 오류가 자꾸 발생했습니다. 메모리 누수의 원인을 찾기 위해 크롬 익스텐션의 React devtool과 크롬 개발자 도구의 Performance로 테스트를 한 결과 무한 스크롤 부분에서 스크롤을 내릴 때마다 메모리 사용량이 늘어나고 있다는 것을 알게 되었습니다. 그래서 더 불러올 데이터가 없음에도 계속 불러오려고 시도하기 때문인가? 라고 추측하였습니다. 무한 스크롤을 구현할 때 사용한 것은 react-queryuseInfiniteQuery 훅과 Intersection Observer API 입니다. 테스트해보니 데이터가 끝나면 더 이상 페치해오지 않았기 때문에 react-query가 아니라 옵저버가 원인이라고 결론짓고 구글링을 하였습니다. 알고 보니 더 이상 데이터가 없으면 옵저버를 종료시켜주었어야 했는데 그 과정을 깜빡하고 넣지 않아서 데이터가 없음에도 옵저버가 실행되고 있었고 그로 인해 메모리 누수가 발생했던 것이었습니다. useEffect에서 observer.disconnect() 메서드를 반환하여 옵저버를 종료하여 해결하였습니다.

  • 코드 검색(필터링)하는 기능을 구현하는 중, 파이어베이스의 기본 기능 중에 단어를 검색하는 기능이 있을 줄 알았는데 알고 보니 단어 검색은 허용되지 않았으며 완전히 일치해야 하거나 배열 형태로 분리가 되어 있어야 했습니다. 태그는 배열, 언어는 단일 단어라서 검색이 가능했지만 제목이나 설명의 경우 문자열이고 단어를 포함하고 있다면 보여주려는 것이었기 때문에 구현할 수 없었습니다. 사전 조사가 부족했던 잘못이지만 이제 와서 DB를 바꾸기에는 늦었다 판단하여 서버에 요청하는 대신 react-query의 select 옵션을 이용하여 받아온 전체 데이터에서 필터링하는 방법으로 구현하였습니다.

Clone this wiki locally