react (40) 썸네일형 리스트형 [React] BATCH를 사용한 리스트 최적화 전략 이미지를 포함한 선수카드 컴포넌트가 무수히 많은(1000장 이상) 리스트가 있을 경우 스크롤을 진행하며 각 선수카드들이 빠르게 리렌더 되는 상황에서 어떤 식으로 최적화를 진행할 수 있을지 고민해보았다.유저가 보유한 모든 선수카드는 앱 진입 초기에 한번에 불러온 뒤 자체적으로 캐싱을 해서 앱 전체에서 사용하고 있다.이미지의 용량이 작지 않아, 동시에 렌더할경우 메모리 초과로 웹앱이 다운되어 virtual grid를 사용해 동적으로 렌더해주고 있었다.이 때 새로 획득한 선수카드의 경우 N태그가 붙는데 확인 후 해당 선수카드가 뷰포트에서 사라질경우 N태그는 제거되어야하는게 기획의 요구사항이였다.관심사 분리, 선수카드 캡슐화를 위해 선수카드를 랩핑하는 HOC를 하나 만들고 interSectionObserver를.. [React] Framer-motion, HOC 관련 Runtime Error import _ from "lodash";type HOC = ( WrappedComponent: any // functional or class component 모두 될 수 있다.) => React.FC;const MergeMotion = ( TargetComponent: React.ComponentType, hoc1: HOC, hoc2: HOC, hoc3?: HOC): React.FC => { return _.flowRight(_.compact([hoc1, hoc2, hoc3]))(TargetComponent);};export default MergeMotion;빛이 지나가는 이펙트를 주기 위해 여러 컨텐트에서 공통으로 사용되고 있는 Glow 컴포넌트가 있다.미션 페이지에서 리스트를 뿌려.. [React] createPortal을 사용한 z-index 제어 룰렛을 구현하던 중 React-Tooltip과 디자인이 맞물려 원하는대로 툴팁의 레이어가 위치하지 않게되는 문제가 발생하였다.우선 룰렛은Wheel(원판)outline(원판 외부 테두리)pointer(룰렛 포인터)tooltip(원판에 있는 각 아이템을 클릭했을 시 나오는 툴팁) 으로 구성이 되어있다.wheel: 1 outline: 2 tooltip: 4 pointer: 3그리고 각 요소의 z-index는 위와 같이 나타나야 한다. 즉 툴팁은 가장 상단에 위치해야하는 상황이다. 이 때 디자인상 컴포넌트 트리 구조가wheel 내부에 outline, tooltip이 위치해야 하였고, pointer는 wheel 외부에 독립적으로 존재해야하는 상황이였다. 이 때 문제는 tooltip이 wheel 안에 있.. [Animation] Framer-motion, React Status에 따른 motion.div의 Animation이 실행되지 않던 이슈 {status !== "RESULT" && ( )} {status === "RESULT" && ( )}위와 같이 React Status에 따라서 조건에 맞는 컴포넌트가 mount, unMount 될 때 각각의 애니메이션이 실행되도록 motion.div를 사용하여 initial 값과 exit, animation의 값을 설정해주었다. 하지만 status가 변경되는 동시에 아무런 애니메이션이 실행되지 않았고, 원인을 찾아보았다. 원인은 생각보다 간단했다,,,Framer Motion이 DOM에서 제거되는 구성 요소를 처리하기 위해 AnimatePresence가 필요하기 때문에 MotionDiv.. Ref와 Polling 방식을 사용하여 게임 데이터 준비 이후 실행 처리 서버에서 응답으로 내려주는 데이터 중 게임 실행 준비가 완료되었다는 상태가 있을 경우, 폴링을 사용하여 로딩 Indicator를 돌리다가 실행 처리를 해줄 수 있다. 위 기능을 간단하게 구현해보기 위해 hook을 하나 만들어주었다. const wrapPollingRef = useRef(false); 우선 Ref 하나를 생성해 준다. const { mutate: play, isLoading } = usePostAPIExEndPoint({ mutation: { onSuccess: (data) => { if (data.result === "SUCCESS") { showLoading(); setGameStatus({ ...gameS.. [Next] Lighthouse 를 사용한 CSR, SSR 성능 차이 비교 Next/Image를 사용하여 이미지 최적화를 하기위해 Next.js로 프로젝트를 진행하고 있지만, 게임 특성 상 Loaing 상태일 경우 loading indicator가 보여지는게 더 적합할 것 같아 프로젝트 전체적으로 CSR을 사용하고 있었다. 이 때, 적합한 페이지는 SSR을 적용해봐도 좋지 않을까 고민하다 상점 페이지에 SSR을 적용해본 뒤 CSR을 했을때와 어느정도의 성능 차이가 있고, 어떤 방식이 더 효율적일지 테스트를 해봐야겠다고 생각했다. 상점은 API에서 특히 더 많은 양의 데이터를 받고 있으며 렌더되는 이미지의 양도 많았다. 우선 React-Query를 사용하고 있는 환경에서 SSR을 적용하기 위해 공식문서에 나와있는 대로 SSR을 위한 초기 설정을 해주었다.https://tanst.. [React] Queue 자료구조를 사용한 Task Scheduling React Cycle 내에서 앱 전반적으로 Task를 Scheduling 할 수 있는 Core Class가 필요했다. Task를 순차적으로 처리해야 하므로 FIFO 구조의 Queue를 사용하였으며, type Task = () => void;class TaskService_ { private queue: Task[] = []; private isProcessing: boolean = false; enqueue(task: Task): void { this.queue.push(task); } execute(): void { if (!this.isProcessing) { this.processQueue(); } } processQueue(): void { this.i.. [React] Debounce를 활용한 중복 요청 방지 각종 이벤트, 미션을 통해 보상을 받는 경우 유저가 Claim 버튼을 단시간 내에 여러번 클릭하여 서버에 여러번 요청이 들어가고 중복 요청으로 인한 비정상적인 응답 및 에러가 발생하는 이슈가 있었다. 위 문제를 해결하기 위해 여러가지 방법을 사용할 수 있었고, 나는 lodash에서 제공하는 debounce 함수를 사용해 문제를 해결했다. View Model에서 mutation을 정의하고 const { claim, claimAll } = ExViewModel();위와 같이 mutate 함수를 구독해 사용하는 과정에서 const debouncedClaimAll = debounce(claimAll, 600); debounce를 걸어주면지정해놓은 시간이 끝나고 하나의 요청을 보낼 수 있었고, 문제를 해결할 .. 이전 1 2 3 4 5 다음