SPACE RUMI

Hi, I am rumi. Let's Splattack!

[IT] 프로덕트 개발/React - 리액트 17

프론트엔드 가이드라인 커서 룰 (FE Guideline Cursor rule)

토스 프론트엔드 가이드라인 기반으로 만든 Cursor rule 입니다코드블럭 내용은 권장패턴입니다 1. 매직넘버 대신 상수 사용설명이 없는 숫자(매직 넘버) 대신 명명된 상수를 사용하여 명확성을 높입니다.이해하기 어려운 값에 의미를 부여하여 가독성 향상유지보수성 향상const ANIMATION_DELAY_MS = 300;async function onLikeClick() { await postLike(url); await delay(ANIMATION_DELAY_MS); // 애니메이션 대기 시간임을 명확히 표시 await refetchPostLike();} 2. 구현 세부사항 추상화복잡한 로직이나 상호작용을 전용 컴포넌트/HOC로 추상화합니다.관심사를 분리하여 인지 부하 감소컴포넌트의 가독성, 테스..

No index signature with a parameter of type 'string' was found on type | 문자열 인덱싱 시그니처 타입에러

key로 직접 접근할때 종종 만날수있는 타입에러 해결방법 1 : 애니추가 [key: string]: any; // 를 추가하거나, 해결방법 2 : key as key of let payload: TestDTO = {}; for (const key in data) { if (data[key]) { payload[key as keyof TestDTO] = data[key]; } } keyof는 객체의 속성 이름들 중 하나를 나타내는 문자열 유니온 타입을 생성한다.

react에서 swiper 사용하기 (feat. reading 'wrapperClass')

다운그레이드 install 해준다 yarn add swiper@6.0.2 다운그레이드 안하면 별짓을해도 안되니까 다운그레이드하자. index.tsx에 스타일을 박아준다 import "swiper/components/navigation/navigation.scss"; import "swiper/components/pagination/pagination.scss"; import "swiper/swiper.scss"; // core Swiper 나는 navigation이랑 pagination을 쓸거기때문에 이렇게 적었다 import 컴포넌트에 사용할 것들을 임포트 해주고 import SwiperCore, { Navigation, Pagination, Parallax } from "swiper"; import ..

[React Hook] useMemo를 알아보자

메모이제이션 useMemo 맨 처음 계산한 값을 메모리에 저장(캐싱)해서, 필요할때 꺼내서 쓴다. 함수로써의 기능도 충분히 가능하지만, useMemo의 의도된 설계가 아니며 지연된 연산을 통해 "값"을 기억하는 게 주된 목적이다. useMemo는 인자를 전달할수없다. (함수의 응답값을 메모할 필요가 없는것이고, 리액트의 useMemo 설계 의도와 어긋난다) 매개변수로 하여금 값을 뽑아내고 싶다면, useCallback 훅을 사용한다. 하지만 이 함수의 응답은 memoize될 수 없다. * 함수는 렌더링이되면 모든 내부변수가 초기화되고, 재할당 과정을 거친다. * 함수형 컴포넌트또한 함수이므로 재렌더링 시 컴포넌트 내 선언된 변수가 초기화되는 과정을 거친다. * state가 변경되면, 함수는 재랜더링 되고..

Typescript IntrinsicAttributes Error

나는 분명 자식 컴포넌트에서 type정의를 제대로 한것같은데 왜 부모에서 에러가 뜨는걸까??? Type '{ images: MediaFile[] | undefined; }' is not assignable to type 'IntrinsicAttributes & MediaFile[]'. type Props를 따로 정의를 해줬다. type Props = { images?: Array; } const GoodsImagesList = ({images}:Props) => { ... } images:MediaFile[] 로 바로 정의할때는 안되었는데.. 따로 Props 타입들을 정의 해주니 해결되었다. 잘 생각해보니, Props는 디스트럭쳐링 형태로 뽑아써야한다는걸 이해했다. (props.images 이렇게..) ..

react에서 html string render / HTML 파싱

아웃룩이 string으로 통 html을 넘겨줘서 이걸 잘 그려야 했는데, 어떻게 파싱해야되지?? iframe으로 해야하나 고민하고 있었다. 그러던 와중 멘토님이 html-react-parser 라는게 있으니 참고하라고 알려주셨다. How to render HTML string in react? how to pick body contents html-react-parser? 등 어떻게 html 안에 또 html을 뿌려주냐 고민하다가 아 어차피 string인데.. 안쪽만 추출해서 파싱해주면 되겠다 싶어서 string을 자르는방법을 선택했다. 좋은방법인지는 모르겠으나 react의 dangerouslySetInnerHTML 보다는 낫다는 판단이다. import parse from 'html-react-parse..

react-query 리액트쿼리를 알아보자 (useQuery, staleTime과 cacheTime)

react-query 리액트 쿼리의 useQuery를 공부해보자. what is query? 쿼리란 무엇이냐.. 쿼리는 데이터베이스 테이블 or 테이블 조합의 데이터 or 정보에 대한 요청이다. 설치 및 세팅 리액트쿼리와 devtools를 설치해준다 yarn add @tanstack/react-query yarn add @tanstack/react-query-devtools QueryClientProvider로 라우터를 감싸주고, 안에 ReactQueryDevtools를 넣어준다. import { BrowserRouter } from "react-router-dom"; import { QueryClient, QueryClientProvider } from "@tanstack/react-query"; im..

React Router v6 설정하기 / match param, protectedRoute

리액트 라우터 설정법을 알아보자 일단 react-router-dom v6를 설치해준다 yarn add react-router-dom v6 App.tsx의 BrowserRouter에 basename을 정해준다.(optional) basename은 url의 prefix를 설정한다. (/rumi-space로 지정하면 모든 router list의 url 앞에 /rumi-space가 붙는다.) import { BrowserRouter } from 'react-router-dom'; import Layout from 'pages/Layout'; import './App.css'; function App() { return ( ); } export default App; 네비게이션이나 header, footer를 고..

[React] localStorage 사용하여 Todo list 만들기

타입설정과 useState list들의 타입을 정해주고, map 돌릴 list state와 새로 추가할 newTodo state를 만들어준다. type Lists = { id:number, title:string, checked:boolean, } ... const [list, setList] = useState([]); const [newTodo, setNewTodo] = useState({ id: new Date().getTime(), title: "", checked: false, }); Mark up 볼만하게 커스터마이징을 해준다. 추가 {list.map((item, index) => { return ( onCheckboxClick(index)} /> {item.title} removeList(i..

[React Hook] useEffect를 알아보자

[2022.01.05] 훅 정리 다시 하면서 한번더 정리해보는 useEffect useEffect(()=>{ 함수() }) // 렌더링 될 때마다 함수 실행 useEffect(()=>{ 함수() },[]) // 처음 렌더링 될때만 함수 실행 useEffect(()=>{ 함수() },[함수]) // 디펜던시 값이 변경될 때마다 실행 useEffect(()=>{ return()=>{ // clean up(정리) // 해당 컴포넌트가 unMount 될때, 다음 렌더링 될 useEffect가 실행되기 전에 실행 } },[]) clean up 예제 function App(){ ... return ( {state && } ) } ... function Interver(props){ useEffect(()=>{ co..

[React] 리스트 추가하고, 클릭시 제거하기 / map, filter

리스트를 추가하고 클릭시 제거하는 UI를 만들어보자. (TODO LIST를 만들어보자~~!) useState 현재 책 리스트를 담을 books Array와, 새로운 book Object를 초기값으로 넣어준다. id는 유니크한 값으로 넣어준다. Book은 id, title, author을 가지고있다. const [books, setBooks] = useState([ { id: 1, title: "1984", author: "George Orwell" }, { id: 2, title: "Lord of the Flies", author: "William Golding" }, { id: 3, title: "Catcher in the Rye", author: "J.D Salinger" }, ]); const [b..

[React] useState를 사용하여 인풋 만들기

useState 안에는 초기값을 적어준다. (객체, 원시타입 등이 올 수 있다.) setter함수를 사용하여 객체를 변경할때는 임시의 복사본을 만들어 새로운 객체를 넣어준다. Hook const [form, setForm] = useState({ nickname: "", description: "", }); const onChangeInputForm = (e: React.ChangeEvent) => { const { name } = e.target; const formTemp = { ...form, [name]: e.target.value }; setForm(formTemp); }; 두개의 인풋을 하나의 함수로 변경하기위해 각각의 input에 name attribute를 지정해준 뒤, e.target에서..

[React] Context api 사용해 로딩 구현하기

context api를 사용해 로딩화면을 간단하게 구현해보자. context폴더에 LoadingContext 파일을 생성한다. context/LoadingContext.tsx import { createContext, useState } from "react"; type LoadingState = { setVisible: (value: boolean) => void; }; export const LoadingContext = createContext({ setVisible: (value: boolean) => {}, }); export function LoadingContextProvider({ children }: { children: React.ReactNode }) { const [visible, ..

[Next] React 에서 Swiper 사용하기

설치하고 Import 하기 yarn add swiper import { Swiper, SwiperSlide } from "swiper/react"; import SwiperCore, { Navigation, Pagination } from "swiper"; import "swiper/swiper.min.css"; import "swiper/components/pagination/pagination.min.css"; 헤맨 점 공식문서 임포트 스타일대로 하니 안된다. import "swiper/css" 이런식으로 하라고 되어있다. (하다하다 하도 안되서 노드모듈 스와이퍼 폴더에 css파일이 있긴한건가 하고 찾아봤는데 있긴하더라..) import swiper css ~~등등 파워 구글링을 했는데 다행히 방법을..

[Next] next 에서 scss 사용하기 및 레이아웃 구조

넥스트에서 scss 사용설정 및 레이아웃 구조 짜기 sass를 설치한다. yarn add sass or npm i sass next.config.js 파일을 수정한다. prependData에는 들어갈 scss파일은, 모든 파일에서 사용할수있으므로 colors정의나 mixin 등을 넣어준다. public아래에 styles파일을 두었으므로 아래와 같이 경로를 설정해줬다. /** @type {import('next').NextConfig} */ const path = require('path') const nextConfig = { reactStrictMode: true, sassOptions: { includePaths: [path.join(__dirname, 'styles')], prependData: "..

[React] JSX 없이 React 사용하기. createElement

어쩌다보니 써야 할 일이 생겨서 기록으로 남긴다. 물론 리액트 공식문서에도 사용법이 잘 나와있다. https://ko.reactjs.org/docs/react-without-jsx.html JSX 없이 사용하는 React – React A JavaScript library for building user interfaces ko.reactjs.org 코드 샘플 e('header', {className: 'custom-header'}, '타이틀'), e('article', {className:'custom-article'}, e('div', {className:'custom-div'}, e('span', {className:'custom-span'}, '샘플') )); e는 React.createEleme..

[React] 리액트 버튼 컴포넌트 만들기 (타입스크립트)

공용으로 사용할 커스텀 버튼 컴포넌트를 만들어보자. CustomButton.tsx (컴포넌트) import React from 'react'; type ButtonTypes = React.DetailedHTMLProps; export interface ButtonProps extends ButtonTypes { onClick: () => void; children: React.ReactNode; } const CustomButton = React.forwardRef( ({ onClick, className, children, ...props }, ref?: React.Ref) => { const classNames = [className, 'custom-btn'].filter(v => Boolean(v)..

반응형