리액트
[React] 리액트 Suspense 톺아보기
[React] 리액트 Suspense 톺아보기
2024.05.06React v18 버전부터 Suspense를 공식적으로 지원한다. Suspense는 컴포넌트 렌더링에 필요한 특정 작업이 완료되지 않았음을 React에게 알려주는 매커니즘이다. 이 특정 작업은 여러가지가 있겠지만 Data Fetching 같은 비동기 작업인 경우가 가장 많다. Suspense를 이용하면, 데이터를 다 불러오지 못한 컴포넌트의 렌더링을 잠시 중단시키고 Loading 화면 같은 다른 컴포넌트를 먼저 보여주도록 할 수 있다. 💡 Suspense는 React Query, SWR 같은 Data Fetching 라이브러리와 함께 사용할 수 있도록 설계됐다. Data Fetching 라이브러리에선 옵션 인자를 전달하는 방식으로 Suspense 기능을 활성화 할 수 있다. 예를들어 useSWR에선 세..
[React] 리액트 Strict Mode 엄격 모드와 사이드 이펙트
[React] 리액트 Strict Mode 엄격 모드와 사이드 이펙트
2024.05.05엄격 모드의 기능CRA로 생성한 React 프로젝트에선 엄격 모드(Strict Mode)가 기본적으로 적용돼 있다. 엄격 모드는 어플리케이션의 잠재적인 문제를 알아내기 위해 리액트에서 제공하는 도구다. 개발 모드에서 함수 컴포넌트 렌더링 / API 호출 등이 중복해서 발생한다면 엄격 모드 때문에 그럴 가능성이 높다.import React from "react";import ReactDOM from "react-dom/client";import App from "./pages/App";const root = ReactDOM.createRoot( document.getElementById("root") as HTMLElement,);root.render({/* ... */}); 엄격 모드는 아래 기능을 제..
[React] 키보드로 조작할 수 있는 드롭다운 자동완성 검색창 구현하기
[React] 키보드로 조작할 수 있는 드롭다운 자동완성 검색창 구현하기
2024.05.05검색창 자동 완성 기능은 , 태그를 이용해 빠르게 구현할 수 있다(참고 포스팅). 키보드 방향키로 옵션을 선택할 수도 있다. 하지만 이 방법은 리스트 요소에 클릭 이벤트를 할당할 수 없는 단점이 있다(검색을 정말 많이 해봤지만 결론은 불가). 검색창에 키워드를 입력한 후 목록에 있는 각 옵션()을 클릭할 때마다 특정 액션을 취해야 한다면 위 방법을 사용할 수 없다. 대안은 React Select 처럼 잘 만든 라이브러리를 사용하거나, 몇 년간 유지 보수한 라이브러리보단 완성도는 조금 떨어질 수 있지만 직접 구현할 수 있다. 아래는 직접 구현한 내용을 기록한 내용. 구현 목표마우스로 리스트 이동 / 선택Enter 키로 선택방향키로 리스트 이동 (Keyboard navigate)스크롤이 생긴 목록에서 방향..
[React] 리액트 드래그앤드롭 파일 업로드 구현
[React] 리액트 드래그앤드롭 파일 업로드 구현
2024.05.05요즘 대부분 웹사이트에서 파일을 업로드할 때 마우스로 원하는 파일을 끌어 놓는 드래그&드롭 기능을 지원한다. 리액트에선 React DnD 같은 라이브러리를 사용할 수도 있지만 HTML5에서 제공하는 드래그 드롭 API를 이용해서 직접 구현할 수 있다. 생각보다 어렵지도 않다. 기본 구조더보기export interface IFileTypes { id: number; object: File; // File 객체}const DragDrop = ( { /* ... */ },) => { const [isDragging, setIsDragging] = useState(false); const [files, setFiles] = useState([]); const fileId = useRef(0);..
[React] Blur 효과를 활용한 이미지 지연 로딩 Image Lazy Loading
[React] Blur 효과를 활용한 이미지 지연 로딩 Image Lazy Loading
2024.05.04웹페이지에서 성능에 영향을 가장 많이 주는 부분이 이미지 / 비디오 같은 미디어 요소다. 특히 이미지는 배너, 제품 사진, 로고 등 페이지 구석구석에서 사용한다. HTTP Archive Data에 따르면 전체 웹페이지 용량의 45%를 이미지가 차지한다고 한다. 이미지를 사용하지 않는건 불가능하지만, 화면에 노출될 때만 이미지를 불러오는 방식으로 페이지 로딩 시간을 단축시킬 수 있다. 이런 방식을 Lazy Loading이라고 한다. Lazy Loading 구현 방법💡 Lazy Loading이 적용된 이미지가 뷰포트에 근접해서 이미지를 로드하면 콘텐츠가 밀려나는 현상이 발생한다. 이를 방지하려면 이미지를 감싸는 컨테이너 요소에 높이 / 너비를 지정하면 된다. Lazy Loading은 크게 Chrome Na..
[React] 두 가지 방법으로 구현해보는 무한 스크롤 Infinite Scroll
[React] 두 가지 방법으로 구현해보는 무한 스크롤 Infinite Scroll
2024.05.041) 스크롤 이벤트를 사용한 방법무한 스크롤은 현재 페이지에서 스크롤바가 마지막 콘텐츠 지점에 있을 때 다음 콘텐츠를 자동으로 불러오는 구현 방식을 말한다. ➊스크롤해서 가려진 영역의 높이와 ➋현재 화면(뷰포트)의 높이를 더한 값이 ➌전체 문서의 높이와 같다면 현재 스크롤이 가장 하단 끝에 도달했다는 걸 알 수 있다. 알아야 할 기하 프로퍼티 ❶ 스크롤해서 가려진 콘텐츠 영역의 높이 : document.documentElement.scrollTop ❷ 현재 화면(뷰포트)의 높이window.innerHeight : 스크롤바 포함document.documentElement.clientHeight : 스크롤바 제외 ❸ 전체 문서의 높이// 문서의 정확한 전체 높이를 구하기 위한 코드const scrollHei..
[React] 리액트 타자기(TypeWriter) 효과 구현하기 feat.제너레이터
[React] 리액트 타자기(TypeWriter) 효과 구현하기 feat.제너레이터
2024.05.03기본 로직타자기로 한 글자씩 입력하는 효과(Typewriter Effect)는 이미 수 많은 라이브러리가 있지만, setInterval 타이머 API를 이용해서 직접 구현할 수 있다. 원래 문장(텍스트)을 한 글자씩 자른 후 가장 앞에 글자부터 하나씩 이어 붙이는 방식이다. // JSconst $content = document.querySelector('.content');function typewriter(target, sentence, speed = 200) { const split = sentence.split(''); let text = ''; let i = 0; const timer = setInterval(() => { if (i 깜빡이는 커서 효과는 | 콘텐츠를 갖는 ..
[React] 리액트 useRef 활용 케이스 모음
[React] 리액트 useRef 활용 케이스 모음
2024.05.03useRef 함수는 current 속성을 가진 ref 객체를 반환한다. ref.current 값을 HTMLElement에 할당해서 해당 요소에 focus하거나, 엘리먼트 크기 등을 확인할 수 있다. ref 객체는 아래 특징을 갖는다. 컴포넌트가 다시 렌더링 돼도 ref.current 값은 그대로 유지한다.ref.current 값이 변경돼도 컴포넌트는 다시 렌더링하지 않는다HTMLElement 뿐만 아니라 숫자 / 문자열 / 배열 등 값을 할당할 수 있다. Case 1 — 리렌더링이 필요 없는 값을 관리할 때 ⭐️useRef는 .current 프로퍼티로 전달된 인자(initialValue)로 초기화된 변경 가능한 ref 객체를 반환합니다. 반환된 객체는 컴포넌트의 전 생애주기를 통해 유지될 것입니다. — ..
[React] 리액트 이미지 미리보기(업로드) 구현 / File API
[React] 리액트 이미지 미리보기(업로드) 구현 / File API
2024.05.02file 타입의 태그와 File API를 이용해 컴퓨터에 저장된 이미지를 업로드할 수 있다. 이미지 태그 자체를 “파일선택” 버튼으로 기능하도록 할 수 있고, 라벨의 스타일을 수정하는 방식으로 “파일 선택”(파일 필드) 스타일을 변경할 수도 있다. 기본 구조업로드한 이미지는 컴포넌트 내부 상태(image)로 관리하고, 업로드 하기 전엔 기본 프로필 사진(fallbackUrl)을 표시하도록 한다. 태그의 type을 file로 명시하면 “파일 선택” 버튼이 표시된다. accept 속성엔 허용할 파일 유형을 .확장자 형태로 입력한다. 확장자는 대소문자를 구분하지 않는다. 여러 값을 입력할 땐 콤마 , 로 구분한다. 특정 타입(MIME 유형)의 모든 확장자를 허용하고 싶으면 타입/* 을 입력한다. 허용하지..
[React] 리액트 라우터 React Router v6 바뀐점 톺아보기
[React] 리액트 라우터 React Router v6 바뀐점 톺아보기
2024.04.30React Router가 v6으로 업데이트 되면서 꽤 많은 부분이 바뀌었다. 공식 문서에선 상세한 마이그레이션 가이드도 제공하고 있다. v6을 사용하려면 React 16.8 버전 이상 사용해야 한다. v6은 이전 버전 대비 번들 사이즈도 70% 이상 줄었다고 한다(패키지 업데이트만으로 번들 크기 최적화가 가능하다는 뜻). Switch → Routes 컴포넌트가 라는 이름으로 변경됐다. 바뀐 이름이 더 직관적인 것 같다. 만 단독으로 사용할 수도 없게 됐다. 를 사용하려면 항상 로 감싸줘야 한다.// v5 // v6 exact 옵션 삭제v6부터 경로가 정확히 일치하도록 매칭 규칙이 바꼈다. 더이상 exact 옵션을 명시하지 않아도 된다. 모든 라우트는 기본적으로 exact 옵션이 붙는다고 보면 된다...
[JS] 정규식으로 검색어 하이라이트 / 문자열 링크 걸기(Linkify)
[JS] 정규식으로 검색어 하이라이트 / 문자열 링크 걸기(Linkify)
2024.04.30검색창에 입력한 키워드와 일치하는 단어를 하이라이트(강조) 하기 위해 split, join 등을 사용할 수 있지만 코드가 다소 복잡해진다. 정규식을 사용하면 깔끔하게 구현할 수 있다. 하이라이터 함수 정의 ▼const getHighlightedText = (text, query) => { const re = new RegExp(`(${query})`, 'gi'); if (query !== '' && text.match(re)) { const parts = text.split(re); return ( {parts.map((part) => part.toLowerCase() === query.toLowerCase() ? ( {part} ..
[React] 리액트로 실시간 검색창 구현하기
[React] 리액트로 실시간 검색창 구현하기
2024.04.30글 수정사항은 노션 페이지에 가장 빠르게 반영됩니다. 링크를 참고해 주세요 Debounce는 이벤트가 연속적으로 발생해도 항상 마지막 이벤트만 처리하는 것을 말하며, Memoize는 이전 연산 결과를 재사용하는 것을 말한다. Debounce와 Memoize를 활용해 불필요한 API 요청을 방지할 수 있다. Animichan은 일본 애니메이션에 등장한 인용문(Quotes)을 제공하는 OpenAPI다. title 매개변수에 애니메이션 제목을 쿼리스트링 보내서 요청하면, 해당 애니메이션의 인용문 세트를 받아올 수 있다. 이 API를 이용해 간단한 검색 어플리케이션을 구현할 수 있다. // Request'https://animechan.vercel.app/api/quotes/anime?title=naruto'..