Who I really am
'공유하기' 동작을 하는 버튼이 여기저기서 쓰여 공통 컴포넌트로 만들었는데,이게 때에 따라 [버튼]이기도, [아이콘]이기도 해야했다. 아래와 같이 컴포넌트, 자체를 넘겨받아 렌더링해줄 수 있도록 했다. import { usePathname, useSearchParams } from 'next/navigation';import Button, { ButtonProps } from '@/components/commons/Button';import { toast } from 'react-toastify';import { ComponentProps, ElementType, ReactNode } from 'react';type Props = { as?: T; // 동적으로 렌더링할 컴포넌트 children?..
쓸 때마다 까먹네... 'use client';import React, { createContext, useContext, useState } from 'react';const SellContext = createContext void; } | undefined>(undefined);export const SellContextProvider: React.FC = ({ children,}) => { const [name, setName] = useState(''); return ( {children} );};export const useSellContext = () => { const context = useContext(SellContext); if (!conte..
// useLocalStorage.tsimport { useState, useEffect, useCallback } from 'react';function useLocalStorage(key: string, initialValue?: T) { const [storedValue, setStoredValue] = useState(() => { if (typeof window === 'undefined') { return initialValue; } try { const item = window.localStorage.getItem(key); return item ? JSON.parse(item) : initialValue; } catch (error) { ..
npm library를 만들어서 배포했는데, 빌드 결과물인 index.es.js 파일에 숨기고 싶은 URL이 포함되어 있었다.빌드 난독화를 해도, env파일에 변수를 넣어도 드러나는 건 당연히 그대로다. (이게 노출된다고 해서 엄청 크리티컬 하진 않지만, 너무 적나라하게 드러나는 것이 불편한 상황) // .envVITE_SOCKET_URL=https://숨기고싶다.com// socketInstance.tsconst url = import.meta.env.VITE_SOCKET_URL;...class SocketInstance { private static instance: SocketInstance; public socket: Socket; private constructor() { // env..
아래와 같이 .../util 과 같은 형태로 import 해올 수 있도록 하는 걸 sub path module 라고 한다.(처음에 뭐라고 칭해야하는지 몰라서 검색하는데 애를 먹었음)import { customUtil } from 'my-library/util'; * subpath를 사용하는 이유 sub path 설정을 위해 살펴봐야할 부분들1) index.ts (배럴 파일들) => 빌드될 대상2) vite.config.ts => 빌드 결과물 설정3) package.json => 외부 프로젝트에서 import 해오는 방식 설정 package.json 파일에 exports 부분을 아래와 같이 작성해주면,외부 프로젝트에서 import { } from 'library/util'; 과 같이 가져다 쓸 수 ..
// iconList.tsxconst iconList = { search: ( ),...}export default iconList // Icon.tsximport { SVGAttributes, forwardRef } from 'react';import iconList from './iconList';import theme from 'styles/theme';type IconProps = { name: keyof typeof iconList; size?: number; color?: keyof typeof theme.colors;} & SVGAttributes;const Icon = forwardRef(function Icon( { name, size = 24, color, ...pro..
내가 만든 custom input에는 기본 input에 내장되어있는 attributes(ex. value, onChange, placeholder...)에내가 정의한 추가요소(ex. size, color, align...)이 덧붙여져야 한다. 이 때, 기본 내장 attributues의 type을 가져오는 코드는 다음과 같다. import styled from 'styled-components';import { InputHTMLAttributes } from 'react';interface InputProps extends InputHTMLAttributes { size?: 24 | 32;}const Input = (props: InputProps) => { return ;};export default..
내가 직접 만든 컴포넌트를 디자인시스템처럼 다른 프로젝트에서 다운받아 사용할 수 있도록 npm에 배포해보자. 1. vite + react + typescript로 프로젝트 만들기npm create vite@latest 2. 불필요한 파일 삭제 (배포될 라이브러리 자체를 그려주는 화면은 필요하지 않기 때문.. 컴포넌트들만 개별로 export 해서 사용할 것임)index.htmlApp.cssApp.tsxindex.cssmain.tsx/assets 폴더/public 폴더 1-1. (선택) npm > pnpm 마이그레이션https://thefirstperson.tistory.com/262 pnpm으로 마이그레이션 하기" data-og-description="1. pnpm 설치npm i -g pnpm ..
프로젝트 폴더구조 📦src ┣ 📂api ┣ 📂app ┃ ┣ 📂(home) ┃ ┣ 📂admin ┣ 📂components ┃ ┣ 📂atoms ┃ ┣ 📂molecules ┃ ┗ 📂organisms ┣ 📂hooks ┣ 📂lib ┣ 📂model ┣ 📂styles ┣ 📂utils ┣ 📜middleware.ts 이름내용api서버 통신 관련 로직(axios, tanstack query)app라우팅될 컴포넌트components재사용 또는 가독성을 위해 쪼개놓은 컴포넌트hooks자주 쓰이는 로직을 커스텀 훅으로 만들어 관리lib외부 라이브러리에서 유틸리티 역할을 하는 모듈을 관리modeldto 모음 (openapi:develop 스크립트 실행 시 자동생성되는 폴더)stylescss 관련 (gl..