react 37

[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..

React.js 2024.10.21

Ref와 Polling 방식을 사용하여 게임 데이터 준비 이후 실행 처리

서버에서 응답으로 내려주는 데이터 중 게임 실행 준비가 완료되었다는 상태가 있을 경우, 폴링을 사용하여 로딩 Indicator를 돌리다가 실행 처리를 해줄 수 있다. 위 기능을 간단하게 구현해보기 위해 hook을 하나 만들어주었다. const wrapPollingRef = useRef(false); 우선 Ref 하나를 생성해 준다. const { mutate: play, isLoading } = usePostAPIExEndPoint({ mutation: { onSuccess: (data) => { if (data.result === "SUCCESS") { showLoading(); setGameStatus({ ...gameS..

React.js 2024.10.08

[Next] Lighthouse 를 사용한 CSR, SSR 성능 차이 비교

Next/Image를 사용하여 이미지 최적화를 하기위해 Next.js로 프로젝트를 진행하고 있지만, 게임 특성 상 Loaing  상태일 경우 loading indicator가 보여지는게 더 적합할 것 같아 프로젝트 전체적으로 CSR을 사용하고 있었다. 이 때, 적합한 페이지는 SSR을 적용해봐도 좋지 않을까 고민하다 상점 페이지에 SSR을 적용해본 뒤 CSR을 했을때와 어느정도의 성능 차이가 있고, 어떤 방식이 더 효율적일지 테스트를 해봐야겠다고 생각했다. 상점은 API에서 특히 더 많은 양의 데이터를 받고 있으며 렌더되는 이미지의 양도 많았다. 우선 React-Query를 사용하고 있는 환경에서 SSR을 적용하기 위해 공식문서에 나와있는 대로 SSR을 위한 초기 설정을 해주었다.https://tanst..

Next.js 2024.06.26

[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.js 2024.05.09

[React] Debounce를 활용한 중복 요청 방지

각종 이벤트, 미션을 통해 보상을 받는 경우 유저가 Claim 버튼을 단시간 내에 여러번 클릭하여 서버에 여러번 요청이 들어가고 중복 요청으로 인한 비정상적인 응답 및 에러가 발생하는 이슈가 있었다. 위 문제를 해결하기 위해 여러가지 방법을 사용할 수 있었고, 나는 lodash에서 제공하는 debounce 함수를 사용해 문제를 해결했다. View Model에서 mutation을 정의하고 const { claim, claimAll } = ExViewModel();위와 같이 mutate 함수를 구독해 사용하는 과정에서   const debouncedClaimAll = debounce(claimAll, 600); debounce를 걸어주면지정해놓은 시간이 끝나고 하나의 요청을 보낼 수 있었고, 문제를 해결할 ..

React.js 2024.05.09

[React] reverse() 함수 관련 크로스 브라우징 이슈

상위 컴포넌트에서 props로 배열을 받아 와 배열 요소를 뒤집어서 뿌려줘야하는 상황에서 크로스 브라우징 이슈가 발생했다. API에서 받아온 원본 배열의 무결성을 지키기 위해 하위 컴포넌트 내부에서 const copiedArr = [ ...apiArr, ].reverse(); 위와 같이 얕은 복사를 해주었다. chrome 환경에서는 reverse가 된 배열이 렌더되었지만, safari 환경에서는 reverse된 배열이 렌더되지 않았다. 디버깅 결과 copiedArr에 reverse된 데이터가 아닌 apiArr의 데이터가 있는 것을 확인하였고, 브라우저간의 렌더 과정에서 변수에 값을 할당하는 시점에 차이가 있을 것이라고 추측했다. dependancy를 걸어 apiArr의 값이 변할 경우 다시 얕은 복사를 ..

React.js 2024.04.18

[Next] Next.js 13 Next/Image, 이미지 최적화

Next/Image에서는 Lazy Loading, 이미지 사이즈 최적화, placeholder, 캐싱 등의 이미지 최적화 기능을 제공한다. lazy loading 기본적으로 다른 속성을 주지 않으면 lazy loading이 적용되어 뷰포트에 이미지가 들어왔을 때 이미지를 로드한다. 만약, loading prop에 ''eager' 값을 주면 뷰포트에 상관 없이 모든 이미지가 동시에 로드된다. 이미지 사이즈 최적화 디바이스 크기에 맞게 이미지의 사이즈가 조절되며, 용량이 작은 webp 포맷으로 변경되는 작업이 Next 서버에서 이루어지게 된다. placeholder CLS(Cumulative Layout Shift), 레이아웃이 흔들리는 현상을 방지하기 위해 placeholder 기능을 제공한다. 이미지가 ..

Next.js 2023.08.29

[Next] Internationalization with next-translate-plugin, i18next in NEXT13

처음 프로젝트를 시작할 때 Next13버전의 App dir은 Stable하지 않다는 이유로, App dir가 아닌 Pages dir를 사용하여 페이지 라우팅을 진행했었다. 이후 기획의 변경으로 프로젝트에 다국어를 지원해야 하는 상황에 직면했다. 이전에 했던 프로젝트 중에 다국어를 적용했었던 경험이 있어 어렵지 않게 적용할 수 있다고 생각했는데, Next13에서는 꽤나 많은 삽질을 하게 되었다.... (30분이면 틀은 잡아놓을 수 있다고 생각했었는데, 동작을 하지 않아 이틀을 날려먹었던 ㅎㅎ) 처음 다국어를 지원하기 위해 사용한 라이브러리는 next-translate이다. nextJS의 공식문서에 Internationalization 관련 section이 있었고 locale 관련하여 기능을 제공해 주는 것..

Next.js 2023.08.22

[React] 리액트 Atomic Design Pattern 설계

프로젝트의 규모가 클수록, 또는 지속적인 버전 관리와 고도화가 필요할 경우 개발 전 프로젝트 설계는 매우 중요하다고 생각한다. 또한 컴포넌트를 구조적으로 설계하여 최하단에서 최대한 재사용이 가능한 컴포넌트들을 확장성 있게 만들어야 한다. 기능은 같지만 디자인이 조금씩 달라지는 Tab, Select box, Modal, Button, Input, 여러가지 Form들을 매번 새로 생성하는 것은 매우 비효율적이고 프로젝트의 코드를 지저분하게 만든다. https://fe-developers.kakaoent.com/2022/220505-how-page-part-use-atomic-design-system/ 아토믹 디자인을 활용한 디자인 시스템 도입기 | 카카오엔터테인먼트 FE 기술블로그 정호일(harry) 카카오..

React.js 2023.03.10