전체 글 164

React의 key에 index를 사용하면 안 되는 이유 (feat. 무한스크롤)

지난주부터 회사 프로젝트에서 다른 팀원 분이 담당하던 feature를 내가 맡게 되었다. 인계를 받으면서 이슈 중 하나가 무한스크롤 기능 중 스크롤을 위로 올려 이전 페이지 아이템을 가져올 때 사용자가 현재 보고 있는 아이템이 화면에 유지되지 않고 새로 받아온 페이지의 첫번째 아이템으로 화면이 튀는 현상이었다. 반면 스크롤을 아래쪽으로 내려서 다음 페이지 아이템을 가져올 때는 현재 보고 있는 아이템이 화면에 그대로 유지되었다. 인계를 해준 팀원 분은 이 이슈를 스크롤 앵커링 문제라고 생각했고, 바닐라 JS를 사용하거나 React에서도 useRef를 사용해서 직접 DOM 조작을 할 때는 위쪽이나 아래쪽 어디로 스크롤을 하든지 스크롤 앵커링이 정상적으로 동작하며, React의 상태를 UI에 렌더링하는 경우 ..

[Git] 커밋은 diff가 아니라 스냅샷이다

들어가기에 앞서 Derrick Stolee가 작성한 Commits are snapshots, not diffs를 번역한 포스팅임을 밝힙니다. 번역에 오류가 있는 경우 댓글로 알려주시면 감사하겠습니다. Git은 뭐가 뭔지 헷갈리기로 악명이 높다. 사용자들은 기대와 어긋나는 용어와 문구를 접하며 곤혹스러워 한다. 이러한 현상은 git cherry-pick이나 git rebase와 같이 '히스토리를 다시 작성'하는 명령에서 가장 두드러진다. 내 경험상 이러한 혼란의 근본 원인은 커밋을 여기저기에서 무엇이 어떻게 바뀌었는지 보여주는 diff로 해석하기 때문이다. 하지만 커밋은 diff가 아니라 스냅샷이다! Git을 감싸고 있는 베일을 걷어내고 레포지토리에 데이터를 저장하는 방식을 살펴보면 Git을 이해할 수 있..

번역 2024.02.18

디자인 패턴 - Command 패턴

들어가기에 앞서 https://www.patterns.dev/vanilla/command-pattern 에 있는 설명과 예시를 바탕으로 하여 관련 주제에 대해 이제까지 공부한 내용을 개인적으로 정리한 포스팅임을 밝힙니다. 명령을 처리하는 객체를 통해 메소드와 실행되는 동작의 결합도를 낮출 수 있다. 특정 작업을 실행하는 객체과 메소드를 호출하는 객체를 분리할 수 있다. 주요 세 가지 클래스: invoker, receiver, command invoker : command를 생성하고 실행하는 역할 나중에 실행할 수 있도록 명령을 대기열(queue)에 넣거나 이미 실행된 명령을 실행 취소하는 데 사용할 수도 있다. receiver : 특정 command를 수신하고 처리 애플리케이션의 다른 클래스나 메소드에 ..

React Query로 에러 처리하기

들어가기에 앞서React Query를 사용해 에러 핸들링을 하면서 많은 도움을 받았던 아티클을 공유하고자 합니다. React Query의 메인테이너인 TkDodo의 블로그 포스팅 React Query Error Handling을 번역한 포스팅임을 밝힙니다. 번역에 오류가 있는 경우 댓글로 알려주시면 감사하겠습니다.   에러 처리는 비동기 데이터 작업, 특히 데이터를 가져오는 작업(fetch)의 필수적인 부분이다. 우리는 모든 요청이 성공하는 것이 아니며, 모든 프로미스(Promise)가 이행(fulfilled)되는 것도 아니라는 사실을 직시해야 한다. 처음부터 이 부분에 집중하지 않는 경우가 많다. 에러 처리는 나중에 생각하고, '잘 되는 케이스'를 먼저 처리하곤 하는 것이다. 하지만 에러를 어떻게 처리..

번역 2024.01.21

시니어 없이 주니어끼리 일하는 방법

지금 다니는 회사는 올 여름 개발팀이 새로 꾸려진 곳으로 구성 인원은 (나를 포함한) FE 신입 2명, BE 1명 등 총 세 명으로 프론트엔드 사수가 없는 곳이다. PM도, 기획도, QA도 없이 세 명이서 일을 분담하여 진행해야 하는 환경이어서 팀 내 개발 문화를 정립해 나가거나 시니어 없이 일을 하는 방법에 대해 늘 관심을 가지고 있던 찰나 지난 우아콘에서 비슷한 고민을 공유해 주는 세션을 발견했다. 30여 분 가량의 세션을 들으며 개인적으로 적용해 보고 싶은 내용들을 정리해 보고자 한다. 시니어 엔지니어란? - 팀 내/외 영향력을 가진다. - 때로는 가장 지루하고 시시한 일(예: 레거시 코드 개선)들을 도맡아 하기도 한다. - 가장 어려운 기술 문제를 풀어낸다. 출처: 윌 라슨, 시니어 엔지니어가 없..

스크랩 2024.01.21

[TypeScript] Clean Code 예제 (1) : 변수와 함수

GitHub - labs42io/clean-code-typescript: Clean Code concepts adapted for TypeScript Clean Code concepts adapted for TypeScript. Contribute to labs42io/clean-code-typescript development by creating an account on GitHub. github.com 이렇게 하지 마라(Bad) vs. 이렇게 해라(Good) 버전의 쉬운 예제들로 정리된 클린 코드 예제이다. 예제들을 쭉 보면서 내가 자주 하는 실수만 따로 모아서 정리해 본다. 1. 변수 단락 평가(short circuiting)나 조건부 대신 default arguments 사용 Bad : func..

스크랩 2024.01.10

디자인 패턴 - Mediator/Middleware 패턴

들어가기에 앞서 https://www.patterns.dev/vanilla/mediator-pattern 에 있는 설명과 예시를 바탕으로 하여 관련 주제에 대해 이제까지 공부한 내용을 개인적으로 정리한 포스팅임을 밝힙니다. 컴포넌트들이 서로 직접 통신하는 대신 중재자 역할을 하는 객체를 통해 서로 통신하도록 한다. 중재자 객체가 요청을 받아 이를 필요로 하는 객체들에게 전달한다. 중재자는 보통 객체나 함수로 구현된다. 사용 예제) 채팅 앱 - 채팅 앱에서 사용자는 메시지를 서로 직접 주고 받지 않는다. - 채팅 서버에 메시지를 전송하고, 서버가 각 사용자에게 메시지를 전달한다. class ChatRoom { logMessage(user, message) { const time = new Date().to..

디자인 패턴 - Observer 패턴

들어가기에 앞서 https://www.patterns.dev/vanilla/observer-pattern 에 있는 설명과 예시를 바탕으로 하여 관련 주제에 대해 이제까지 공부한 내용을 개인적으로 정리한 포스팅임을 밝힙니다. Observer 패턴에서는 특정 객체를 구독할 수 있는데, 구독하는 주체를 Observer라고 하고, 구독 가능한 객체를 Observable이라고 한다. 이벤트가 발생할 때마다 Observable은 모든 Observer에게 이벤트를 전파한다. Observable 객체는 보통 3가지 주요 특징을 포함한다. observers : 이벤트가 발생할 때마다 전파할 Observer들의 배열 subscribe() : Observer를 observers 배열에 추가한다. unsubscribe() :..

2023년 한 해를 돌아보며

여러 가지 변화가 많은 한 해였다. 6년 간 프리랜서 통번역사로 일하던 생활을 정리하고, 작년 하반기부터 시작한 부트캠프를 수료했다. 수료식 바로 다음날 포르투갈행 비행길에 올라 3주 간 여행을 하고 돌아와 휴식과 충전의 시간을 가졌다. 이후 한 달여의 취직 준비 기간을 거쳐 웹 프론트엔드 개발자로 입사했다. 감사하게도 1개월 만에 수습 기간을 끝내고 정규직이 되었다. 입사 이후 개인적으로는 1년 동안 두 집 살림을 하던 생활 역시 정리하고, 한 곳에 제대로 둥지를 틀었다. 4년 동안 살던 집을 빼고 이사를 했고, 짐 정리를 전부 마치는데 거의 두 달 반 정도가 걸렸다. 평일에는 여유가 나지 않아 주말 밖에 시간이 없었던 데다가 개인 일정이 있거나 컨디션이 좋지 않아 휴식을 취하거나 하면 한두 주가 그냥..

돌멩이 하나 2023.12.23

id는 숫자여야 할까, 문자열이어야 할까?

프로젝트 요구사항 중 수천~수만 개의 문장이 담긴 문서(document)에 문장 별로 책갈피(bookmark)한 문장을 별도 조회할 수 있는 기능이 추가되었고, 이에 대한 화면을 구현하는 중이었다. 서버에서는 다음과 같은 모양의 bookmark 데이터들이 담긴 배열을 보내준다. (참고로 데이터 필드명이나 구조는 프로젝트 코드와 정확히 일치하는 것이 아닌 포스팅을 읽는 이의 이해를 돕기 위한 예시이다.) { id: 1, source: 'Before we begin.', target: '시작하기 전에.', memo: '', document: { id: 3, name: 'Dance with Chance #1', }, } 위와 같은 데이터가 담긴 배열(이하 bookmarks라고 통칭)을 GET 요청으로 받아온 ..