돌멩이 하나/에러는 미래의 연봉 22

Image 컴포넌트의 src에 문자열 경로를 지정했을 때 이미지가 뜨지 않는 이슈

지난주 next.js로 토이 프로젝트를 배포하고 작성했던 포스팅에서 Image 컴포넌트의 src에 문자열 경로를 지정하는 경우 이미지 엑박이 뜨고, StaticImageData로 바꿨을 때는 정상적으로 이미지가 뜨는 원인을 알았다. 원인을 파악하기에 앞서 StaticImageData를 콘솔에 찍어보니 다음과 같은 객체를 볼 수 있었다.  import HeroImage from '/public/hero_256x256.png';export default function Home() { console.log(HeroImage); return ( );}// HeroImage 객체{ src: '/_next/static/media/hero_256x256.0d595165.png', height: ..

next.js로 만든 토이 프로젝트 배포

next.js 예제와 강의를 보며 틈틈이 만들었던 프로젝트를 이번 주말 배포했다. 나중에 내가 볼 요량으로 배포하면서 알게 된 것들 몇 가지 간단하게 정리해본다.  Vercel Postgresvercel로 배포했고, DB도 vercel postgres를 사용했다. 무료 플랜으로 1개의 DB를 제공하고 있다. 처음 DB를 생성하고 프로젝트와 연결할 때 총 6개의 region 중에 하나를 골라야 한다. 아시아 지역은 싱가폴이 유일해서 Singapore를 선택했다. region은 한 번 선택하면 그 이후에 변경이 안 되기 때문에 유의해야 한다. We recommend choosing the same region as your Serverless and Edge Functions for the fastest r..

custom event로 렌더링과 무관한 데이터 추적하기

프로젝트에서 일종의 에디터 역할을 하는 화면이 있어서 `contenteditable` 속성을 사용해 사용자가 텍스트를 편집할 수 있게 하고 있다. React에서 `contenteditable` 속성을 사용하는 것은 쉽지 않은데, 특정 요소에 `contenteditable` 속성을 사용하려고 하는 경우, 다음과 같은 경고를 한다.  Warning: A component is contentEditable and contains children managed by React. It is now your responsibility to guarantee that none of those nodes are unexpectedly modified or duplicated. This is probably not in..

무한 스크롤 이슈 디버깅 과정

이번주에 버그로 등록된 이슈 하나를 해결했던 과정이 재미있어서 기록으로 남겨두는 게 좋겠다는 생각이 들었다. 먼저 제보된 이슈는 다음과 같았다.특정 문서를 업로드했을 때 편집 화면에서 스크롤 이동이 되지 않고, A 기능이 동작하지 않음  A 기능은 편집 화면 내에서 스크롤 이동시 뷰포트에 들어와 있는 아이템을 대상으로 서버에 배치로 요청을 한 다음, 해당 응답 결과를 가지고 화면에 특정 UI로 렌더링하는 기능이었기 때문에 이건 스크롤 이슈였다.  먼저 해당 현상을 재연하기 위해 버그가 발생한다고 제보한 계정으로 접속해 해당 문서를 확인해 보았다. 그런데 내 컴퓨터에서는 스크롤도, A 기능도 정상적으로 동작했다. 내 컴퓨터는 맥북이었고, 버그를 제보한 분의 컴퓨터는 윈도우 데스크탑이었다. 그래서 팀 공용 ..

Checkbox 컴포넌트를 만들면서 알게 된 것들

1. 요소의 indeterminate 상태 :indeterminate - CSS: Cascading Style Sheets | MDNThe :indeterminate CSS pseudo-class represents any form element whose state is indeterminate, such as checkboxes that have been set to an indeterminate state with JavaScript, radio buttons which are members of a group in which all radio buttons are uncheckdeveloper.mozilla.org 체크박스 그룹이 있을 때 한 개 이상의 아이템에 체크가 되었을 때 Check al..

React Query를 활용한 테이블에서 데이터 정렬하기

기존 테이블 컴포넌트에 정렬 API를 연동하는 작업을 하던 중 다음과 같은 상황을 만났다. (간단한 예제 코드를 만들어 보고자 했으나 공개 API로 같은 현상을 재현하기가 어려웠다 😢) 먼저 테이블은 antd의 table 컴포넌트로 테이블의 각 열마다 정렬 버튼이 있다. 정렬 버튼을 처음 누르면 오름차순 정렬(ascend), 두번째로 누르면 내림차순 정렬(descend), 세번째로 누르면 정렬 취소 순서로 동작하고, 사용자가 특정 열의 정렬 버튼을 누를 때마다 해당 열이 ascend인지 descend인지 알 수 있다. 이 정보를 바탕으로 서버에 쿼리 스트링으로 정렬된 데이터를 요청한다. 그러자 특정 열의 정렬 버튼을 누를 때마다 화면이 full refresh가 되었다...! 😰 정렬 버튼을 한번씩 눌러서..

React ErrorBoundary와 react-query를 사용하여 예외 처리 설계하기

예외 처리를 설계하며 고민한 내용들을 간략하게 정리해 보았다. 프로젝트마다 필요한 예외 처리가 다르고, 구현 방식도 여러 가지가 있기에 개발의 많은 부분이 그렇듯 정답이 없는 것 같다. 나중에 시간이 흐른 뒤 이 포스팅을 보면 분명 '왜 이렇게 했지?'라고 생각할 것 같다. 😇 하지만 같은 고민을 하는 누군가에게 조금이나마 도움이 될 수 있기를 바란다. 1. 에러의 분류 먼저 위의 도식을 참고하여 프로젝트 상황에 맞게 에러를 분류해 보았다. 사용자에게 에러가 발생한 이유를 설명하고 사용자의 액션을 유도하는 장치를 제공하는 것을 예외 처리의 핵심으로 두었다. 1. 예상 가능한 에러 a. 사용자 입력 값에 대한 에러 - 에러 발생 상황 예시: 로그인 시 틀린 비밀번호를 입력하거나 회원가입시 중복 아이디 또는..

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

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

ant design과 tailwind css 충돌 이슈 해결

UI 라이브러리를 처음 사용해 보고 있다. 개발의 많은 부분이 트레이드 오프인데 UI 라이브러리 도입도 이러한 부분이 있는 것 같다. pros. - 직관적이고 깔끔한 UX 컴포넌트 지원 - 빠른 개발 속도 - 웹 접근성 준수 cons. - 커스터마이징의 한계 - 이슈가 생기면 내가 코드를 잘못 작성한 탓인지 라이브러리 자체의 이슈인지 매번 찾아봐야함 antd 도입을 결정하고 난 후 매일 antd 레포의 이슈를 뒤지는 삶을 살고 있다 해도 과언이 아니다. 그 첫 시작은 tailwind와의 충돌이었다. tailwind가 설치된 프로젝트에 antd를 추가로 설치하고 버튼 컴포넌트를 불러왔더니 버튼이 보이지 않았다 😱 개발자 도구를 보면 antd primary button의 배경색 #1677ff 가 tailwi..

styled-components에서 custom props 사용하기

기술 과제를 진행하면서 styled-components를 사용해 공통 ui 컴포넌트를 만들던 중 input 입력란의 텍스트 정렬을 다르게 가져가야 할 필요가 생겼다. 아래의 화면 이미지와 같이 우편번호 input은 중앙정렬, 그 외에 input은 일반적인 좌측 정렬로 화면 디자인이 구성되어 있었다. 이를 위해 input ui 컴포넌트에서 prop으로 textAlign 값을 줘서 제어하려고 시도했다. // 공통 ui 컴포넌트 선언부 export const Input = styled.input` box-sizing: border-box; width: ${(props) => props.width || 'inherit'}; height: 40px; padding: 9px 13px; border: 1px soli..