전체 글 103

Three.js 에서 한글 폰트 사용하기

React Three Fiber와 drei에서 한글 텍스트를 사용할 때 엑스박스로 표시되는 문제가 생겨서 이 문제를 해결하는 방법을 찾았다.  문제 상황  평균 객단가이 코드에서 한글 텍스트가 엑스박스(□□□)로 표시된다.Three.js의 Text 컴포넌트는 일반 TTF/WOFF 폰트를 직접 사용할 수 없기 때문이다.  해결 방법Three.js에서 한글을 표시하려면 특별한 JSON 형식의 폰트 파일이 필요함. 폰트 변환 과정TTF 폰트 준비: 사용할 한글 폰트 파일을 준비한다.facetype.js 변환: TTF 파일을 Three.js 호환 JSON으로 변환한다. 변환된 폰트 사용하기  평균 객단가  주의사항올바른 JSON 형식: 변환된 JSON 파일에는 glyphs, familyName, ascend..

Three.js 2025.03.24

Zustand 캐시 문제로인한 데이터 로드 이슈

최근 POS 시스템을 개발하면서 Zustand를 상태 관리 라이브러리로 사용했다. 이 과정에서 특정 상황에서 메뉴 데이터가 제대로 로드되지 않는 문제를 발견했다. 특히, 스토어 전환 후 currentMenus가 빈 배열로 남아 있거나, 결제 후 /pos 페이지로 돌아올 때 카테고리와 메뉴가 사라지는 현상이 발생했다. 이 문제를 해결하기 위해 캐시 로직을 점검하고 수정했다. 이번 글에서는 그 과정을 정리하고, Zustand 캐시 문제를 해결한 방법을 공유하고자 한다. 문제 상황POS 시스템에서 사용자는 로그인 시 storeId를 선택하고, 해당 스토어의 카테고리와 메뉴를 로드한다. Zustand 스토어(usePosStore)에서 fetchMenusByCategory 함수를 통해 메뉴 데이터를 가져오고, 이..

Zustand 2025.03.22

JS프론트엔드 기초 개념 정리

화살표 함수와 일반 함수의 차이화살표 함수(Arrow Function)는 ES6에서 도입된 함수 표현식으로, 기존의 function 키워드를 사용하는 일반 함수와 차이점이 존재한다.차이점this 바인딩화살표 함수는 자신만의 this를 가지지 않고, 선언된 스코프의 this를 그대로 사용한다.일반 함수는 호출 방식에 따라 this가 달라진다.arguments 객체화살표 함수는 arguments 객체를 가지지 않으며, 필요할 경우 rest parameter (...args)를 사용해야 한다.일반 함수는 arguments 객체를 사용할 수 있다.사용 방식화살표 함수는 짧고 간결하게 작성할 수 있으며, 익명 함수로 주로 사용된다.일반 함수는 생성자 함수, 프로토타입 메서드 등에서 사용될 수 있다.function..

JavaScript 2025.03.12

토큰 사용시 로컬스토리지 사용의 보안 문제

웹 애플리케이션에서 인증 정보를 저장하는 방식 중 하나로 **로컬스토리지(LocalStorage)**를 활용하는 경우가 많다. 하지만, 로컬스토리지에 토큰을 저장하는 것은 보안적으로 취약한 방식이며, 특히 XSS(Cross-Site Scripting) 공격에 노출될 가능성이 높다.  로컬스토리지의 보안 취약점XSS 공격에 취약함로컬스토리지는 브라우저의 JavaScript 코드에서 직접 접근 가능하다.만약 공격자가 XSS를 통해 악성 스크립트를 실행하면, 로컬스토리지에 저장된 Access Token을 탈취할 수 있다.예를 들어, 웹사이트에 XSS 공격이 성공하면 다음과 같은 코드로 토큰을 훔칠 수 있다.console.log(localStorage.getItem("access_token"));이 토큰을 공격..

Axios 2025.03.12

react : useQuery 에서 key 가 의미하는 것

useQuery에서 key는 캐싱과 데이터 업데이트를 관리하는 데 중요한 역할을 하는 고유 식별자다. React Query에서는 이 key를 기반으로 데이터를 가져오고, 상태를 캐싱하고, 리렌더링을 최적화한다. useQuery의 key란?key는 쿼리를 구별하는 식별자로 사용된다.같은 key를 가진 쿼리는 React Query의 캐시를 공유한다.key가 변경되면 해당 쿼리는 다시 실행된다.import { useQuery } from '@tanstack/react-query';const fetchUser = async () => { const res = await fetch('/api/user'); return res.json();};function UserProfile() { const { data..

카테고리 없음 2025.03.12

Next.js 하이드레이션 (Hydration)

Next.js 하이드레이션 (Hydration) 정리Next.js에서 하이드레이션(Hydration)이란 서버에서 렌더링된 HTML을 클라이언트에서 React 컴포넌트로 변환하는 과정이다. 즉, 서버에서 생성된 정적인 HTML이 클라이언트에서 React의 상태와 이벤트를 갖춘 동적인 페이지로 변환되는 과정을 의미한다. 하이드레이션이 필요한 이유SSR/SSG 이후 React 기능 활성화Next.js는 SSR(Server-Side Rendering)이나 SSG(Static Site Generation)으로 HTML을 미리 생성한다.하지만 서버에서 내려준 HTML에는 React의 이벤트 핸들러나 상태가 포함되지 않음.클라이언트에서 하이드레이션을 통해 React가 takeover(인수)하면서 이벤트 및 상태를 ..

Next.js 2025.03.12

첫 프론트엔드 개발자 면접 후기

오늘은 강남에 왔다.멀어서 잘 안오는 강남, 이력서를 400개 넘게 넣고 있는 지금 이라면 강남은 집앞 편의점보다 더 가벼운 발걸음으로 출근 할 수 있을 듯. 첫 면접을 봤는데 준비가 많이 부족했다. 대화하는 부분에 있어서는 분위기가 좋아서 편하게 해주시는 면접관분들이 감사했지만 기술 면접에 들어가니 막상 대답 할 수 있는 것들이 너무 없고, 모르는 것을 모르는 상태가 되어 버렸다. 아는 걸 조금이라도 더 내 비추려고 했어야 하는데 무엇을 골라서 말해야 할지 머릿속이 짧은 순간 복잡해졌다. 그래도 그런대로 준비한 몇개 안되는 대답은 해서 그래도 며칠간 연습한 보람은 있었다. 아무 것도 대답하지 못한다면 그거야말로 사람들의 시간을 뺏는 셈이 될 수도 있으니 그러고 싶지는 않았다. 하지만 예상한 것보다 기술..

카테고리 없음 2025.03.12

React 상태 관리 문제 해결 과정

Next.js로 주문 내역 페이지를 만들고 있었다. 왼쪽에 주문 목록을 띄우고, 클릭하면 중간 섹션(Middle Section)에 상세 정보가 나와야 하는 구조였다. 근데 주문을 클릭해도 중간 섹션이 빈 채로 남아 있었다. 콘솔을 열어보니 이런 로그가 찍혀 있었다:page.tsx:189 Selected order in useEffect: undefinedpage.tsx:227 Order not found for selectedOrderId: 164API 호출은 잘 됐는데, 왜 데이터가 안 보이는 걸까? 하루를 이거 풀어보느라 씨름했다. 원인 파악코드를 뜯어보니 문제는 상태 관리에 있었다.상태 두 개로 나뉘어 있었다:sortedGroups: /api/orders/daily에서 받은 주문 데이터를 날짜별로 ..

Next.js 2025.03.07

캐시 활용으로 누락된 서버데이터 처리

POS 시스템에서 메뉴 데이터를 효율적으로 다루기 위해 usePosStore.ts라는 파일을 수정했다. 여기서 중요한 작업은 메뉴의 고유 번호(menuId)를 항상 확보하는 것이었다. 서버에서 데이터를 받아올 때 menuId가 빠져 있으면 문제가 생기는데, 이를 해결하기 위해 캐시라는 저장소를 활용했다. 문제: menuId가 빠진 데이터POS 시스템은 주문을 표시할 때 각 메뉴의 고유 번호(menuId)가 필요하다. 예를 들어, "라떼"라는 메뉴를 삭제하려면 그 메뉴의 menuId를 알아야 한다. 근데 서버에서 데이터를 받아올 때 가끔 이런 식으로 menuId 없이 오는 경우가 있었다: { "menuName": "matcha", "totalPrice": 4500, "totalCount": 1} 로그..

Next.js 2025.03.01

React : useMemo로 성능 최적화하기

useMemo란? useMemo는 React에서 값(또는 연산 결과)을 메모이제이션(memoization)하여 불필요한 계산을 방지하는 Hook. 컴포넌트가 렌더링될 때마다 반복되는 비용이 큰 연산을 피하고, 캐싱된 값을 재사용할 수 있게 해준다. 결제 페이지에서 initialTotal과 changes 계산이 매 렌더링마다 반복되는 문제를 해결하기 위해 React의 useMemo를 활용했다. 이 과정에서 useMemo의 동작 원리와 사용법을 깊이 파악할 수 있었다.문제 상황기존 코드에서는 initialTotal이 매번 새로 계산되었다:const initialTotal = selectedItems.reduce((acc, item) => acc + item.price * item.quantity, 0); c..

Next.js 2025.02.26
반응형