react

· TIL
tailwind-merge 라이브러리import { clsx, type ClassValue } from 'clsx';import { twMerge } from 'tailwind-merge';export function tailwindMerge(...inputs: ClassValue[]) { // clsx를 사용하여 입력된 모든 클래스네임을 결합하고, // 이를 twMerge에 전달하여 최종 병합된 클래스네임을 반환합니다. return twMerge(clsx(...inputs));} 간단히 위처럼 사용할 수 있습니다.GPT 쌤의 자세한 설명을 첨부합니다.clsx와 twMerge를 함께 사용하여 tailwindMerge 함수를 구현하면, 이 함수는 clsx만을 사용하는 경우보다 더 강력하고 ..
· TIL
scrollIntoView이 좋은 걸 몰랐다니..요소를 뷰포트 내에 보이도록 자동 스크롤해주는 기능이라고 합니다.. 아래 예시에서는 div 의 아래에 버튼들이 있고인덱스를 state 로 관리하는 상황인데요. 인덱스가 변할 때 마다 useEffect 가 실행되고자동으로 인덱스에 해당하는 버튼이 화면의 중앙에 오게 됩니다. 많이 써먹을 것 같습니다!useEffect(() => { if (scrollRef.current) { const selectedButton = scrollRef.current.children[ selectedIndex ] as HTMLElement; if (selectedButton) { se..
· TIL
당겨서 새로고침을 막고싶을 때모바일 버전 개발을 하다보면당겨서 새로고침이 되는 것이 매우 귀찮습니다. 특히 화면내에서 드래그 해야하는 요소들이 있을 때자꾸만 새로고침 되어서 짜증납니다. 그래서 방법을 찾아 보았습니다.역시 방법이 있었고요.. 전에는 div 같은 걸로 감싸서 높이를 제한하고 뭐 어쩌고 했던것 같은데그냥 간단하게 해결하는 방법이 있었습니다. 검색해보면 body 에다가 넣든지 html 에다 넣든지 하라고하는데저는 특정페이지에서만 막고 싶어서아래처럼 해보았습니다. useEffect(() => { document.documentElement.style.overscrollBehavior = 'none'; return () => { document.documentElement...
· TIL
Auth session missing!수파베이스 auth 사용중에자꾸만 마주치는 auth session missing!이것을 해결하기 위해 별 방법을 다 써보고 했지만레딧이나 깃헙이슈에도 같은 문제를 겪는 사람들이 많은 걸 보니뭔가 수파베이스에 문제가 있는 것 같기도 합니다. 아무튼 서버측에서 날리는 fetch 의 결과가tanstack query 의 prefetch query 와 함께 쓸 때 미들웨어서는 getUser 가 잡히지만prefetch query에서는 안 잡힌다거나혹은 자꾸 있었다 없었다 하는 문제를 해결해보고자(십중팔구 auth session missing...)안되면 fetch를 할 때 쿠키를 직접 같이 배달해보자라고 생각했습니다.그래서 fetch 함수를 다음과 같이 작성했습니다.fetche..
· TIL
얼러트 모달이 여기저기 필요해서서버, 클라이언트 관계없이 아무데서나 호출해서 쓸 수 있도록아래처럼 사용하고 있었습니다. 그런데 이 방법에 문제가 조금 있었습니다.그냥 써도 무방한 정도였지만 해결해보기로 하였습니다. 문제는 번들 사이즈가 너무 크다는 점 이었습니다.여기저기서 호출 하는 함수인데 무거우면 안될 것이라 판단했습니다.원래 버전원일을 찾아보니 createRoot 를 하기 위해 가져온ReactDom 이 번들사이즈가 132kb 정도로 무거웠습니다.그래서 이것을 제거하고 다른 방법을 사용하기로 했습니다.하지만 그러면 컴포넌트를 사용해서 아무데서나 body에얼러트 모달을 부착할 수가 없었습니다.import CustomAlert from '@/components/organisms/common/CustomA..
· TIL
Lazy LoadingLazy loading은 Next.js에서 애플리케이션의 초기 로딩 성능을 개선하는 데 도움을 주며, 경로를 렌더링하는 데 필요한 JavaScript의 양을 줄여줍니다. 클라이언트 컴포넌트와 가져온 라이브러리의 로딩을 지연시킬 수 있으며, 필요할 때만 클라이언트 번들에 포함되도록 합니다. 예를 들어, 사용자가 모달을 열려고 클릭할 때까지 모달의 로딩을 지연시킬 수 있습니다. Next.js에서 lazy loading을 구현하는 두 가지 방법이 있습니다:next/dynamic을 사용한 동적 가져오기React.lazy()와 Suspense를 사용기본적으로 서버 컴포넌트는 자동으로 코드 분할이 되며, 스트리밍을 사용하여 서버에서 클라이언트로 UI 조각을 점진적으로 전송할 수 있습니다. La..
· TIL
state와 UI를 리턴하는 커스텀 훅이 필요해우리에겐 state와 UI(컴포넌트)를 리턴하는 커스텀 훅이 필요합니다. 여기서 state는 전역상태로 관리되면 안되는 상황이므로커스텀 훅에서 리턴하는 state 는 독립적이어야 합니다. 또한 비슷한 UI를 반복적으로 사용해야 하는데 렌더링해야하는데이터종류는 2가지(여정테마/버디즈성향)인 상황입니다. 따라서 커스텀 훅의 리턴은 named export가 될 수 없으므로 객체가 아닌 배열어야 합니다.그렇다면 [컴포넌트, 스테이트] 이렇게 반환하기만 하면 될 것 같습니다.리턴할 컴포넌트먼저 리턴할 컴포넌트를 atoms 레벨에 만들었습니다.type PreferThemeProps = { selectedTheme: string[]; handleThemeCha..
· TIL
Sharp를 사용하지 않고 이미지를 10px로 리사이즈하고 Base64로 변환하는 작업을 클라이언트 측에서 수행하려면 HTML5 Canvas API를 사용할 수 있습니다. 이 방법은 이미지의 크기 조정을 수행하고 결과를 Base64로 인코딩하는 데 사용할 수 있습니다.다음은 클라이언트 측에서 이 작업을 수행하는 방법입니다:1. 이미지 로드 및 Canvas를 사용한 크기 조정 및 Base64 변환 함수const loadImage = (src: string): Promise => { return new Promise((resolve, reject) => { const img = new Image(); img.crossOrigin = "anonymous"; // CORS가 필요한..
· TIL
이미지를 10px 사이즈의 base64 문자열로 변환하는 함수를 작성하기 위해, 먼저 이미지를 불러와서 크기를 조정한 후 base64 형식으로 인코딩해야 합니다. 서버 사이드에서 이미지를 처리하기 위해 sharp 라이브러리를 사용할 수 있습니다. 이를 Next.js API 라우트를 통해 구현할 수 있습니다.다음은 이미지를 10px 사이즈로 변환하고 base64 문자열로 반환하는 API 라우트를 작성하는 방법입니다:1. sharp 라이브러리 설치먼저 sharp 라이브러리를 설치합니다.npm install sharp2. API 라우트 작성src/pages/api/getBase64.ts 파일을 생성하고 다음 코드를 추가합니다:import type { NextApiRequest, NextApiResponse }..
· TIL
nextjs 14버전에서 pwa 를 셋업하는 방법에 대해 알아보았습니다.1. next-pwa 설치yarn add next-pwa yarn add -D webpack2. next.config.mjs 수정아래와 같이 수정합니다.import withPWAInit from "next-pwa";const withPWA = withPWAInit({ dest: "public",});/** @type {import('next').NextConfig} */const nextConfig = {};export default withPWA(nextConfig);3. 퍼블릭에 manifest.json/public 폴더에 아래와 같이 manifest.json 파일을 작성합니다.{ "name": "My Next.js P..
· TIL
Step 7. 프로바이더 로그인 버튼 예시"use client";import useAuth from "@/hooks/useAuth";import { showAlert } from "@/lib/openCustomAlert";import { usePathname } from "next/navigation";import { FcGoogle } from "react-icons/fc";function GoogleLogInButton() { const { loginWithProvider } = useAuth(); const pathname = usePathname(); const handleClickGoogle = async () => { if (pathname === "/recove..
· TIL
여기에서 이어집니다.Step 4. signup & login & logout 라우트 핸들러 작성이메일회원가입 / 로그인 / 로그아웃 용 라우트 핸들러를 작성합니다.회원가입 / 로그인 로그아웃시에는 여기로 요청날리면 됩니다.(3편 콘텍스트api 활용 에서 자세히 설명)// api/auth/signup/route.tsimport { createClient } from "@/supabase/server";import { NextRequest, NextResponse } from "next/server";export async function POST(request: NextRequest) { const data = await request.json(); const name = data.name a..
· TIL
1. 라이브러리 설치리액트 인터섹션 옵저버 설치npm install react-intersection-observer탠스택쿼리 설치npm install @tanstack/react-query @tanstack/react-query-devtools2. 탠스택쿼리 프로바이더 설정프로바이더 만들기"use client";import { isServer, QueryClient, QueryClientProvider } from "@tanstack/react-query";import { ReactQueryDevtools } from "@tanstack/react-query-devtools";function makeQueryClient() { return new QueryClient({ default..
· TIL
React Router의 navigate 함수는 보통 React 컴포넌트 안에서 사용됩니다. 그러나, 일반 JavaScript 파일에서 navigate 함수를 사용하려면 React Router의 내비게이션 기능을 직접 접근할 수 있어야 합니다. 이를 위해, React 컨텍스트나 커스텀 훅을 활용할 수 있습니다.Step-by-Step GuideReact Router의 내비게이션 컨텍스트 사용: React 애플리케이션의 루트 레벨에서 내비게이션 컨텍스트를 설정합니다.커스텀 훅을 사용하여 내비게이션 함수 제공: 내비게이션 기능을 커스텀 훅으로 캡슐화하여 일반 JavaScript 파일에서 접근할 수 있게 합니다.일반 JavaScript 파일에서 내비게이션 함수 사용: 일반 JavaScript 파일에서 내비게이션..
· TIL
Suspense 컴포넌트를 Provider 또는 Layout처럼 분리하여 재사용하는 법을 알아보았습니다.이렇게 하면 코드를 더 깔끔하게 유지하고, 여러 곳에서 Suspense 기능을 쉽게 사용할 수 있을 것 같습니다..Step-by-Step GuideSuspenseProvider 컴포넌트 생성:Suspense 컴포넌트를 감싸는 SuspenseProvider 컴포넌트를 생성하여, fallback UI를 중앙에서 관리할 수 있습니다.App.js에서 SuspenseProvider 사용:SuspenseProvider 컴포넌트를 App 컴포넌트에서 사용하여, 하위 컴포넌트들이 지연 로딩되는 동안 보여줄 UI를 지정할 수 있습니다.예제 코드SuspenseProvider.jsimport React, { Suspens..
· TIL
try...catch 문에서 에러를 던질 때, 두 가지 방법 사이의 차이를 알아보겠습니다에러를 그대로 던지는 경우 (throw error):새로운 에러 객체를 생성하여 던지는 경우 (throw new Error(error.message)):1. throw errortry { // something to try...} catch (error) { console.error("Error fetching data:", error); throw error;}기존 에러 객체: catch 블록에서 잡힌 원래의 에러 객체를 그대로 다시 던집니다.스택 트레이스 보존: 원래의 스택 트레이스가 보존됩니다. 즉, 에러가 처음 발생한 위치와 관련된 디버깅 정보가 유지됩니다.에러 타입 보존: 원래 에러의 타입이 ..
· TIL
class 프로퍼티 선언방법 두가지방식 1:class Book { constructor( public title: string, public author: string, public publishedDate: Date ) {}}방식 2:class Book { public title: string; public author: string; public publishedDate: Date; constructor( title: string = '타이틀', author: string = '저자', publishedDate: Date = new Date() ) { this.title = t..
· TIL
로그인, 회원가입, 인풋의 기본 템플릿을 정리합니다.인풋// Input.tsximport { ComponentProps, useId } from "react";type InputProps = { label?: string; required?: boolean; type? : "text" | "password";} & ComponentProps;function Input({ label, required, id, type = "text", ...props }: InputProps) { const inputUid = useId(); const inputId = id || inputUid; return ( {label && ( ..
· TIL
Awaited, ReturnType타입스크립트에서 Awaited 와 ReturtnType 에 대해 공부하였습니다.타입스크립트에서 Awaited>를 사용하여 타입을 지정하는 방식은 함수 foo의 반환 타입이 Promise일 때 유용합니다. 이를 통해 foo 함수의 비동기 작업이 완료된 후의 결과 타입을 추론할 수 있습니다.Awaited 타입 유틸리티Awaited는 타입스크립트에서 비동기 함수의 결과 타입을 추론하는 데 사용되는 유틸리티 타입입니다. Promise가 반환하는 값의 타입을 추출합니다.ReturnType 타입 유틸리티ReturnType는 주어진 함수 타입 T의 반환 타입을 추출하는 유틸리티 타입입니다.typeof 연산자typeof 연산자는 변수나 함수의 타입을 가져오는 데 사용됩니다.예제// 비..
· TIL
이번엔 tanstack query 의 공식문서 중 Advanced Server Rendering 항목을 공부하였습니다.아래 내용을 정리합니다. 이번 포스팅 내용이 app router 에 해당합니다.Advanced Server Rendering이 가이드에서는 스트리밍, 서버 컴포넌트 및 Next.js 앱 라우터와 함께 React 쿼리를 사용하는 모든 것을 배울 수 있습니다. 이 가이드에 앞서 서버 렌더링 및 하이드레이션 가이드를 읽어보시는 것이 좋으며, 이 가이드에서는 SSR과 함께 React Query를 사용하기 위한 기본 사항을 설명하고 성능 및 요청 워터폴과 프리페칭 및 라우터 통합에 대해서도 유용한 배경 지식을 담고 있습니다. 시작하기 전에 SSR 가이드에 설명된 초기데이터 접근 방식은 서버 컴포넌..
· TIL
tanstack query 의 공식문서 중 Prefetching & Router Integration 항목을 공부하였습니다.아래 내용을 정리합니다. Prefetching & Router Integration특정 데이터가 필요할 것으로 예상되는 경우 미리 가져오기를 사용하여 캐시를 해당 데이터로 미리 채우면 더 빠른 환경을 제공할 수 있습니다.몇 가지 다른 프리페칭 패턴이 있습니다:이벤트 핸들러에서컴포넌트에서라우터 통합을 통해서버 렌더링 중(라우터 통합의 또 다른 형태)이 가이드에서는 처음 세 가지를 살펴보고, 네 번째는 서버 렌더링 및 수화 가이드와 고급 서버 렌더링 가이드에서 자세히 다룰 것입니다. 프리페칭의 구체적인 용도 중 하나는 요청 워터폴을 피하는 것인데, 이에 대한 자세한 배경과 설명은 성능 ..
· TIL
createObjectUrl파일을 다룰때, 이미지 파일등의 미리보기를 띄우거나 할 경우에 유용하게 사용할 수 있다고 합니다!이 간단한걸 몰라서 막 base64로 바꾸고 했었습니다 ㅠ.ㅜ사용법은 매우 간단합니다. 그냥 URL.createObjectUrl(file) 입니다.. function handleFileInput(event) { const file = event.target.files[0]; const url = URL.createObjectURL(file); // URL을 사용하여 파일을 미리 보기 document.getElementById('preview').src = url; } // HTML // // 간단하지만 몰랐던 것! 정리..
· TIL
이번 개인과제에서는 250개의 배열을 리턴하는 api 를 사용해야 했습니다.그런데 이것을 한번에 화면에 렌더링 하자니 무언가 마음에 들지 않아서react-intersection-observer 를 사용해보고 싶어졌습니다.1 ) 전체 배열을 부분 배열화 하여 2차원 배열 생성이를 위해서 250 길이의 배열을 20개씩 나누기로 했습니다.그래서 이를 수행하는 간단한 util 함수를 작성하였습니다.// util 함수function makeChunkArray(array: T[], chunkSize: number): T[][] { const chunks = []; for (let i = 0; i { const fetchCountries: FetchCountries = async () => { ..
· TIL
네이버 지도 관련 마지막입니다.네이버 지도 api 에서 정보창을 만들 때 기본적으로 문자열만 받는데,이부분을 리액트 컴포넌트로 할 수 없을까 고민하다가 나온 결론입니다.React.createRoot, React.render 조합function SetInfoWindowContent( type, searchedValue, htmlAddresses, infoWindow, place = null, navigate = null, marker = null, user = null, contracts = []) { // 임시 컨테이너 생성 const container = document.createElement('div'); container.style...
· TIL
리팩토링은 미래의 나에게.. ㅋㅋ참고용으로만 올려야겠습니다.네이버지도 with React - Step by Step 2initGeocoder.jsfunction initGeocoder( infoWindow, map, searchInputRef, searchButtonRef, marker, setSelectedGeoData, setSelectButtonDom, user) {map.addListener('click', (e) => { searchCoordinateToAddress( infoWindow, map, e.coord, setSelectButtonDom, setSelectedGeoDa..
· TIL
팀플 주간이 끝났습니다!팀원분들의 노력 덕분에 무리없이 프로젝트를 완료 할 수 있었습니다. 아웃소싱 프로젝트(aka 외부 api 사용 프로젝트)에서 저희는 네이버 지도 api 를 활용하여운동 모임 사이트를 기획했고, 5일이라는 짧은 시간동안 요구사항을 대부분 구현했습니다.오늘은 그 중 제가 담당했던 네이버 지도 api 에 관한 사항을 정리하려고 합니다.네이버지도 with React - Step by Step 1네이버 지도 api script 동적 로드네이버 지도 api 를 이용하기 위해서는 https://openapi.map.naver.com/openapi/v3/maps.js 라는 스크립트를 로드해야 합니다index.html 에서 script 태그로 로드해도 되지만, 좀 더 동적인 방식을 고려하였습니다사..
· TIL
Zustand 스토어에서 expends의 초기값을 설정하는 방법으로 useQuery를 사용할 수 있지만, useQuery는 React 컴포넌트 내부에서만 사용할 수 있습니다. 대신 Zustand와 Tanstack Query를 함께 사용하여 상태를 관리할 수 있는 패턴을 사용할 수 있습니다.다음은 Zustand와 Tanstack Query를 함께 사용하여 초기 데이터를 설정하는 방법입니다.1. Tanstack Query와 Zustand 설정먼저, react-query 라이브러리와 Zustand를 설치해야 합니다.npm install @tanstack/react-query zustand2. Zustand 스토어 설정Zustand 스토어를 설정하고, expends 상태를 관리하는 방법을 정의합니다.import..
· TIL
리액트에서 Context API를 사용하지 않고 Tanstack Query를 사용하여 Supabase의 인증 상태를 관리하고 확인하는 방법은 다음과 같습니다.1. Tanstack Query 설정import { QueryClient, QueryClientProvider, useQuery } from 'react-query';import { supabase } from './supabaseClient';const queryClient = new QueryClient();function App() { return ( );}2. 인증 상태 확인const fetchSession = async () => { const { data: { session }, error } = await ..
· TIL
useMutation, Optimistic Update 패턴useMutation 훅은 비동기 작업(특히 서버에 데이터를 추가, 수정, 삭제하는 작업)을 처리할 때 사용됩니다.이 예제에서는 addTodo 함수가 서버에 새로운 할 일을 추가하는 비동기 작업을 수행합니다.useMutation 훅을 사용하여 이러한 작업의 상태(성, 실패, 진행 중 등)를 관리하고, 해당 작업이 애플리케이션의 상태에 미치는 영향을 제어할 수 있습니다.주요 콜백 및 설정mutationFn:mutationFn은 실제로 변이를 수행하는 비동기 함수입니다. 여기서는 addTodo 함수가 이 역할을 합니다.onMutate:onMutate는 변이가 시작될 때 호출됩니다.서버에 요청을 보내기 전에 로컬 상태를 업데이트하여 응답 지연을 사용자..
· TIL
useQuery 의 queryKey 배열에 대해 설명해주세요useQuery의 queryKey는 React Query에서 캐싱 및 상태 관리의 핵심 요소입니다. queryKey는 쿼리의 고유한 식별자로 사용되며, React Query는 이를 기반으로 데이터 캐싱, 데이터 무효화, 리패칭 등을 관리합니다.queryKey의 역할데이터 캐싱 및 식별:queryKey는 쿼리의 고유 식별자입니다. 동일한 queryKey를 가진 쿼리는 동일한 데이터 캐시를 공유합니다.React Query는 queryKey를 사용하여 캐시된 데이터를 저장하고 검색합니다.쿼리 무효화 및 리패칭:특정 queryKey를 가진 쿼리를 무효화하면, React Query는 해당 queryKey에 대한 데이터를 무효화하고, 필요에 따라 다시 패칭..
adminisme
'react' 태그의 글 목록