본문 바로가기

React

Pagination Component를 선언형으로 구현하기 키워드: 선언형 프로그래밍, Pagination, React 상황 팀원이 개발한 Pagination UI 로직이 절차형으로 되어있었다. 코드를 이해하기 어렵고 유지보수가 힘들어질거란 걱정이 들어 코드를 선언형으로 리팩토링하고자 한다. 아래는 기존 코드의 예시이다. (코드의 일부이기 때문에 이해가 되진 않을 것이다.) ... const searchSiblings = (page: number, dist: number) => { const left = page - dist; const right = page + dist; if (right >= MAX_PAGE && left = _pagerCount) { return; } } if (left > MIN_PAGE) { leftSiblings.push(left.. 더보기
iframe으로 Vue to React Migration 준비하기 키워드: vue to react migration, iframe, postMessage, contentWindow, window.parent 상황 Vue2로 작성된 프로젝트가 있다. 프로젝트의 복잡성, 인수인계, 유지보수 등을 고려하여 React로 migration하기로 결정했다. 한 번에 옮기기엔 거대한 프로젝트이므로, 기존 로직을 유지하면서 점진적으로 migration하고자 한다. 해결 과정 기존 Vue 로직을 그대로 유지하면서 migration하는 방법은 iframe을 이용하는 것이다. React 프로젝트를 새로 만들어 특정한 기능을 만든 후, 해당 기능만 Vue에서 iframe으로 가져오면 된다. Vue와 React 프로젝트를 development mode로 실행할 경우, 각각 :8080(Vue).. 더보기
스탬프 투어 미션 구현하기(feat. firestore, redux saga) 프로젝트: SNU FESTIVAL 키워드: firestore, redux saga 상황 축제 사이트를 구현할 때 미션 기능을 추가해달라는 요청이 들어왔다. 페이지 곳곳에 5개의 미션이 나누어져 있고 특정 미션을 클리어하면 미션 카드에 그림 스탬프가 채워지는 형식이었다. 웹사이트 전체에 걸쳐 미션 진행 상태를 다뤄야 해야하기 때문에 redux를 이용하여 브라우저 내 상태 관리를 하는 것이 좋다고 생각했다. firebase auth 로그인을 한 상태로 미션이 이루어지기 때문에 firestore에 uid(사용자 계정의 unique id)를 문서 이름(key)으로 하고, 미션 진행 상태를 value로 저장하는 방식으로 미션 데이터를 관리하기로 했다.(GET/SET을 할 때 대상 문서를 쉽게 찾을 수 있다.) 해.. 더보기
선언형 Portal, Modal 컴포넌트 구현하기 프로젝트: loplat UI 키워드: portal, createPortal, modal, createElement 상황 여러 프로젝트에서 Modal을 사용할 일이 많아 loplat UI에서 컴포넌트를 제공해주고자 한다. 렌더링부에서 container DOM과 children content만 선언하여 쉽게 react portal 기능을 사용할 수 있도록 하고자 한다. // 원하는 형태 children children 해결 과정 먼저 container와 chlidren을 prop으로 받아 createPortal을 실행하는 Portal 컴포넌트를 만든다. import React from 'react'; import ReactDOM from 'react-dom'; export interface PortalPro.. 더보기
Toast 컴포넌트 구현하기 프로젝트: loplat UI 키워드: Toast, class, setTimeout 상황 기존 loplat UI의 Toast 컴포넌트는 react-hot-toast 라는 라이브러리를 fork 한 후, 사내 디자인에 맞게 변형하여 사용하고 있었다. Toast 컴포넌트의 변경사항이나 버그가 있을 때 코드의 흐름을 이해하기 어려웠고, 필요한 기능에 비해 용량이 매우 컸다.(20Kb) 직접 Toast를 구현하는 것이 유지보수, 용량, 성능 모든 면에서 더 좋을 것이다. 해결 방법 아래의 예시 코드와 같이 Toast 를 App에서 렌더링하고, toast 인스턴스를 통해 함수를 트리거하는 것으로 설계했다. 'Toast' 컴포넌트와 'toast' 인스턴스를 연결하는 것이 구현의 핵심이다. ... toast.succes.. 더보기
리액트에서 달팽이 모양으로 움직이는 애니메이션 만들기 프로젝트: 채식 지도(가명) 키워드: snail array, transform translate, algorithm 상황 리액트에서 무한 영역 UI 만들기(feat. requestAnimationFrame, useRef) 에서 만들었던 피드백 페이지가 있다. 새로운 피드백을 작성했을 때, 포스트잇 하나가 추가되어야한다. 기존 포스트잇들이 달팽이 모양으로 움직여서 새로운 포스트잇을 위한 공간을 만든다면 재미있는 UI가 될 것이다. 해결 과정 먼저 한 변의 길이가 n인 달팽이 배열을 만드는 함수를 작성한다. 달팽이 배열 문제는 여러 가지 방법으로 풀 수 있을 것인데, 짧지만 어려운 방법 대신 길지만 직관적인 알고리즘으로 작성했다. '-1'로 초기화된 배열의 (0, 0)에서 시작하여, for문을 통해 dire.. 더보기
useLayoutEffect로 최초 렌더링 UX 개선하기 프로젝트: 공우 홈페이지 키워드: useLayoutEffect, useEffect, react hook flow 상황 공우 홈페이지에서 한글/영어 번역을 지원하고자 한다. 기획상 한글/영어 페이지를 각각의 URL로 분리하는 것이 아니라, 하나의 페이지에서 상태 값을 이용하여 언어를 결정한다. (다크모드와 비슷한 구조) 현재 언어를 localStorage에 저장해두어 새로 고침을 하거나 사이트를 벗어났다가 돌아와도 언어가 유지되도록 구현했다. const [language, setLanguage] = useState('Korean'); // 기본 값은 Korean useEffect(() => { setLanguage(localStorage.getItem('language') ?? 'Korean'); }, [.. 더보기
리액트에서 무한 영역 UI 만들기(feat. requestAnimationFrame, useRef) 프로젝트: 채식 지도(가명) 키워드: infinite UI, requestAnimationFrame, mouse event, touch event, useRef 상황 피드백 페이지는 포스트잇이 무한히 나열된 UI로 구현하고자 한다. 마우스나 모바일기기의 터치를 이용하여 원하는 방향으로 움직일 수 있어야한다. 또한, 손가락을 움직이다가 뗐을 때 속도가 점점 감속되면서 멈춰야한다. 해결 과정 무한한 것처럼 보이기 위해선 어떤 장치가 필요할까? 를 먼저 고민해보았다. 내가 생각한 답은 자연스럽게 특정 영역을 계속 순환하는 것이었다. 복사 영역 복사 영역 복사 영역 복사 영역 메인 영역 복사 영역 복사 영역 복사 영역 복사 영역 위의 표와 같이 실제로 유의미한 '메인 영역'이 중앙에 위치하고 그 주변은 복사 영.. 더보기

반응형