react에서 long press 구현하기
·
dev/React
웹에서 long press를 구현할 일이 생겼다. 원했던 기능은 타임 테이블에서 꾹 누르기 + 드래그를 통해 예약하고자 하는 날짜를 지정하는 것! PC에서는 drag만 있어도 해당 기능을 구현할 수 있지만, tablet에서는 스크롤 이벤트와 drag 기능이 중첩되어 의도한 동작이 이뤄지지 않기 때문에... long press를 추가해 이를 해결하고자 했다. 기본적인 long press의 개념은 1. 사용자가 화면을 누른 상태에서, 지정 시간이 지난 후에야, 특정 동작이 수행된다. 2. 지정 시간이 흐르기 전에 사용자가 화면에서 손을 떼면, 특정 동작이 수행되지 않는다. 우선, 화면을 눌렀을 때/손을 땠을 때는 pointer event를 통해 감지할 수 있다! https://ko.javascript.inf..
Inversion of Control
·
dev/React
하루 내내(그리고 지금도) 고민하는 문제. 컴포넌트의 제어권을 어디까지 위임할 것인가! 0부터 시작해 모든 것을 만들어가는 스타트업의 특성 상, 애플리케이션 UI나 기능은 시시각각 변하기 마련이다. 이전에는 이런 변화가 생기면 승질부터 났었다. 유지보수의 어려움을 들며 변경 사항을 (최대한) 막으려 한다던지... 당장 해당 변경사항만을 반영하기 위해 주먹구구식으로 컴포넌트를 작성한다던지... 하지만 클린 아키텍처를 읽은 후 부터, 소프트웨어 개발을 다른 시각으로 바라보게 되었다. → 소프트웨어는 변화에 빠르게 대응하기 위해 존재하는 것! → 수정사항과 변화는 항상 생길 수 있다! 따라서 중요한 건, 해당 변경사항을 빠르고, 안전하게 반영하는 것! 그리고 이를 위한 수단으로... 컴포넌트 제어의 역전에 대..
Reconciliation (재조정)
·
dev/React
React의 비교(diffing)알고리즘 why? render = 해당 함수가 처음부터 끝까지 실행되는 것 = React element tree를 만드는 것 state, props가 갱신되면 render()함수는 새로운 React element tree를 반환 React → 가장 효과적인 방법으로 생성된 element tree에 맞는 UI 갱신! 하나의 트리를 다른 트리로 변환하기 위한 최소 연산? → O(n3)… 굉장히 비싼 연산… React는 두 가지 가정에 기반한 O(n) 복잡도의 알고리즘 구현! 서로 다른 타입의 두 엘리먼트는 서로 다른 트리를 만들어낸다. 개발자가 key prop을 통해, 여러 렌더링 사이에서 어떤 자식 엘리먼트가 변경되지 않아야 할지 표시해줄 수 있다. 비교 알고리즘(Diffi..
React Query - Placeholder, Initial Data
·
dev/React
React Query initial data 더 나은 사용자 경험 추구는 프론트엔드 개발자의 숙명과도 같다. 이를 위해 수많은 노력을 하게 되는데... 대표적인 사례가 → 서버에서 데이터를 받기 전 화면을 어떻게 그릴 것인가! 일반적으로는 로딩 화면을 보여주면 되지만... 이 역시 '최선의' 방안이라고 보기는 어려울 테다(기다리는 걸 좋아하는 사람은 없으니!) 그렇다면 '최선의' 방안이란 뭘까? → 서버 데이터를 받아오기 전에, 화면을 그려주는 건 어떨까? React Query는 이를 위해 여러 유용한 도구들을 제공한다. prefetchQuery : 추후 필요한 데이터 미리 가져오기 keepPreviousData : 쿼리 키가 변경되더라도 마지막으로 success된 data 유지 Placeholder, ..
React Query - keepPreviousData
·
dev/React
다음과 같은 상황을 겪었다. 필요한 요구 사항은 반려동물 상세 페이지에서, 상단 카드 버튼을 눌러(나, 음, 뭉치), 해당 반려동물의 상세 데이터를 불러오는 것! 이 때 불러올 반려동물의 id를 state로 관리하고, 해당 state를 useQuery의 key값으로 전달해, 상단 카드 버튼을 눌러, id가 변경될 때마다, 해당 useQuery가 fetch 되도록 하였다. 여기서 문제점은... 맨 처음 해당 페이지에 들어왔을 때 (해당 반려동물 상세 데이터 요청이 success되기 전에) 발생하는 깜빡임을 해결하기 위해 placeholderData를 넣어줬는데, 상단 카드 버튼을 눌러 해당 query가 fetching 됨에 따라, 해당 query의 data가 최초에 넣어준 placeholderData가 되..
useReducer
·
dev/React
useReducer 왜? 사실 현재 운영 중인 서비스에서 useReducer를 굳이 사용할 필요를 느끼지 못했다. 앵간한 상태는 useState와 Redux를 통해 관리했고... 결정적으로, reducer의 강점인 이전 값에 의존적인 상태의 업데이트가 필요한 경우가 딱히 없었기 때문! 하지만 최근 리팩토링 및 안정성에도 신경을 쓰면서, useReducer를 적재적소에 사용해 setter를 직접적으로 노출시키지 않음 + 익명 함수 호출X 등의 이점을 챙겨가고자 한다! reducer 너무 유용하게 사용되는 reduce 메서드! Array.prototype.reduce() 배열의 각 요소에 대해 주어진 리듀서 (reducer) 함수를 실행하고, 하나의 결과값을 반환한다. useState 앱에서 빈번히 이뤄지는..
useTransition hooks
·
dev/React
when? 일반적인 경우 우리는 상태가 업데이트 되었을 때, 이것이 화면에 즉시 반영되길 원한다. 하지만 업데이트가 화면에 반영되는 것을 연기해야할 때도 존재할 수 있다. ex) 한 페이지에서 다른 페이지로 이동 시, 다음 화면에 표시될 데이터가 load되지 않았을 경우 → 바로 다음 페이지로 넘어가기보다, 이전 화면에 오래 머무는 것이 더 나은 사용자 경험 (이러한 패턴 구현이 이전 React에서는 쉽지 않았다고 한다) React 18의 Concurrent mode → 이를 위한 새로운 tools 제공! useTransition hooks 1. 실제로 Concurrent 모드를 사용하고 있는지 확인 - 해당 Concurrent 모드 동작을 위해 ReactDOM.createRoot()보다, ReactDO..
patch-package 사용하기
·
dev/React
역시 groomer 페이지를 만들다 발생한 issue. 메인 페이지의 Carousel 기능(흔히 말하는 슬라이드! 영어로는 Carousel로 표현한다)을 위해... Swiper라는 라이브러리를 사용했다. https://swiperjs.com/react Swiper React Components Swiper is the most modern free mobile touch slider with hardware accelerated transitions and amazing native behavior. swiperjs.com 다양한 효과를 적용할 수 있고, 커스텀도 손쉬운데... 문제는 기본 색상이나 위치를 디자인에 맞게 수정하는 것! 개발 환경에서는 node_modules에서 해당 스타일 파일을 찾아 수..