[REACT] REACT 관련 CS 총 정리 해보자

김현수·2023년 12월 3일
0

React

목록 보기
7/29


📰 React 총 정리


DOM (문서 개체 모델)

  • Dom

    • 웹 문서용 프로그래밍 인터페이스
    • 페이지 구조를 개체 트리로 나타내므로 스크립트 문서 구조, 스타일 및 내용 변경 가능

  • React Dom

    • React 가 DOM 과 상호작용하는 방식
    • React 는 실제 DOM 의 경량 사본인 Virtual DOM 을 생성
    • 컴포넌트의 상태 변경을 기반으로 Virtual DOM 을 업데이트
    • Virtual DOM 과 일치하도록 실제 DOM 을 효율적으로 업데이트

SPA (단일 페이지 애플리케이션)

  • 완전히 새로운 페이지를 로드

  • 서버의 새로운 데이터로 현재 웹 페이지를 동적으로 다시 작성

  • 사용자와 상호작용하는 웹 애플리케이션

  • 효율적인 업데이트 및 렌더링 시스템으로 인해 SPA 구축에 매우 적합

  • 즉, 처음 페이지가 로드된 후에는 사용자와 상호 작용하여
    새 페이지가 아닌 현 페이지 내 요소를 동적으로 다시 작성


State & Props

  • State
    • 컴포넌트의 상황에 대한 정보 보유
    • 시간이 지남에 따라 변경될 수 있음
    • 리렌더링을 트리거

  • Props
    • 읽기 전용 구성 요소
    • 상위 컴포넌트에서 하위 컴포넌트로 데이터 전달

리액트 훅

  • useState
    • 기능적 컴포넌트에 상태 추가 가능

  • useEffect
    • 데이터 가져오기, 구독 또는 수동 DOM 조작 같은 기능적 컴포넌트의 부 작용

  • useMemo
    • 성능 향상을 위해 비용이 많이 드는 계산 메모

  • useCallback
    • 불필요한 리렌더링을 방지하기 위해 콜백함수 메모

  • useRef
    • DOM 요소에 직접 액세스하거나 변경 가능한 값을 저장

  • useContext
    • 트리의 모든 수준을 통해 소품을 전달하지 않고 컴포넌트 간에 값 공유

CSR & SSR

  • CSR (클라이언트 측 렌더링)
    • 브라우저는 JS 를 사용하여 컨텐츠 렌더링
    • 대화형 애플리케이션에 적합
    • 일반적으로 사용

    • 프로세스
      • 초기 로드
        (Root div 와 JS 파일에 대한 링크를 포함한 최소 HTML 로드)
      • JS 실행
        (React 프레임워크를 포함하는 JS 실행, JS 는 DOM 조작하여 브라우저에 HTML 콘텐츠 구축)
      • 데이터 가져오기
        (JS 는 데이터를 가져오기 위해 추가 HTTP 요청 생성 후 데이터가 페이지 렌더링)

  • SSR (서버 측 렌더링)
    • 서버가 페이지의 초기 HTML 을 렌더링
    • SEO 및 초기 로드 시간이 향상
    • Next.js 에서 사용 가능

    • 프로세스
      • 초기 로드
        (브라우저가 서버에 페이지 요청)
      • HTML 생성
        (서버는 애플리케이션 로직을 실행하고 필요에 따라 데이터를 가져온 다음 요청된 페이지에 대한 전체 HTML 생성)
      • 응답
        (서버는 완전히 구성된 HTML 을 브라우저로 다시 보낸 다음 이를 렌더링)

SSG (정적 사이트 생성)

  • 페이지가 빌드시 사전 렌더링
  • 콘텐츠가 자주 변경되지 않는 웹 사이트에 사용
  • Next.js 에서 사용 가능
  • SEO, 성능 향상

상태 관리 라이브러리

  • React-Query
    • 애플리케이션의 서버 상태 관리
    • 비동기 데이터 가져오기, 캐싱하기, 업데이트를 위한 후크 제공

    • 캐싱 및 동기화 (서버 상태 관리)
      • stale-time
        • 가져온 데이터가 최신 상태로 유지되는 시간
        • 이 시간이 지나면 해당 쿼리가 다시 사용될 때 데이터를 다시 가져옴
      • cache-time
        • 사용되지 않거나 오래된 데이터가 가비지 수집되기 전 캐시에 남은 시간
import { useQuery } from '@tanstack/react-query';

const fetchProjects = async () => {
  const response = await fetch('/api/projects');
  return response.json();
};

const Projects = () => {
  const { data, isLoading } = useQuery(['projects'], fetchProjects, {
    staleTime: 1000 * 60 * 5, // 5 minutes
    cacheTime: 1000 * 60 * 60 // 1 hour
  });

  if (isLoading) return <div>Loading...</div>;

  return <div>{JSON.stringify(data)}</div>;
};

  • Redux
    • JavaScript 앱을 위한 예측 가능한 상태 컨테이너
    • 전역 상태 관리가 복잡한 대규모 애플리케이션에 적합

  • Recoil
    • Redux 보다 더 현대적인 접근 방식 React 용 상태 관리 라이브러리
    • 더 간단한 API 와 더 나은 성능 제공

비동기 & 동기 활용한 ES 기술

  • Promises
    • 비동기 작업의 최종 완료 또는 실패를 나타내는 객체

  • async-await
    • Promises 보다 편안한 방식으로 작업
    • 비동기 코드를 동기식으로 보이게 하고 이해하기 쉬움
import React, { useState, useEffect } from 'react';

const fetchData = async () => {
    const response = await fetch('https://api.example.com/data');
    const data = await response.json();
    return data;
};

const MyComponent = () => {
    const [data, setData] = useState(null);

    useEffect(() => {
        fetchData().then(setData).catch(console.error);
    }, []); 

    return <div>{data ? JSON.stringify(data) : 'Loading...'}</div>;
};

export default MyComponent;

React 컴포넌트 디자인의 세 가지 핵심 요소

  • 재사용성
    • 구성요소를 최대한 재사용 가능하게 설계

  • 상태 관리
    • 상태를 효율적이고 명확하게 관리

  • 성능
    • 리렌더링을 주리고 로딩 시간 개선을 위해 컴포넌트 최적화

  • (+ @) 유지보수성 ( 업데이트 용이, 협업을 위해 )

TypeScript 사용

  • 사용 이유

    • 유형 안전성 : 컴파일 타임에 유형 관련 오류 포착, 런타임 오류 줄이기
    • 더 나은 도구 : 더 나은 자동 완성, 코드 탐색 및 리팩토링 도구 제공
    • 가독성 및 유지 관리성 : 유형은 문서 역할을 하며 코드베이스를 더 쉽게 이해하고 유지 관리 가능
  • 제네릭

    • 단일 데이터 유형에 국한 X
    • 모든 데이터 유형에서 작동하는 구성 요소 및 기능을 구현 가능
function identity<T> (arg: T): T {
	return arg;
}
  • 인터페이스
    • 객체의 모양을 정의하는 데 사용
    • 어떤 속성과 메서드가 예상되는지 명확
interface User {
	name: string;
	age: number;
}

Webpack & Babel

  • Webpack

    • 모듈 번들러
    • 종속성이 있는 모듈을 사용하고 해당 모듈을 나타내는 정적 자산 생성
  • Babel

    • Javascript 컴파일러
    • ES15+ 를 브라우저용 이전 버전과 호환되는 버전으로 변환

Redux

  • Dispatch
    • 저장소에 작업을 보내는 데 사용되는 메서드
  • Action
    • 발생한 상황을 설명하는 개체
  • Store
    • 응용 프로그램의 상태를 보유
  • View
    • 상태의 UI 표현

Webpack4 / Webpack45 빌드과정 & 번들링 최적화

  • Webpack 은 최신 웹 개발에 사용되는 강력한 모듈 번들러 및 빌드 도구
  • 종속성이 있는 모듈을 가져와 해당 모듈을 나타내는 정적 자산을 생성

  • Webpack4
    • 빌드
      • 진입점(기본값 )부터 시작하여 Webpack은 번들링 작업을 시작 (./src/index.js)
      • 매핑되는 종속성 그래프를 작성
    • 최적화
      • 코드 분할
      • 트리 셰이킹 (사용하지 않는 코드 제거)
      • 최소화 (CSS, JS 파일 축소)
      • 효율적인 로더 사용 (node_modules, 필요한 파일만 사용하도록 로더 구성)
      • 환경 구성 (최적화를 위해 production 으로 설정, process.env.NODE_ENV)

  • Webpack5
    • Webpack4 비해 빌드 개선점
      • Persistent Caching
        • 생성된 웹팩 모듈 및 청크를 캐싱하여 빌드 속도 개선
      • 모듈 페더레이션
        • 독립 빌드간에 동적으로 코드 공유
      • 향상된 트리 셰이킹
        • 알고리즘 개선, 패키지 부작용 구성에 대한 지원 추가
      • 클리너 번들
        • 기본적으로 Node.js 코어 모듈에 대한 폴리필이 포함 X
      • Asset Module
        • 외부 로더 없이 자산을 처리
    • 최적화
      • 영구 캐상 (캐시를 활용하여 빌드 시간 개선)
      • 모듈 연합 (서로 다른 프로젝트 간 라이브러리/코드 효율적 공유)
      • 트리 셰이킹 및 부작용 개선 (package.json 올바른 sideEffects 플래그가 있는지 확인)
      • 번들 크기 줄이기 (불필요한 폴리필 및 라이브러리 제거)
      • 자산 모듈 (기본 제공 자산 모듈을 사용하여 자산 처리)
      • 성능 향상 (청크 최적화, 중복된 모듈 최소화

  • Webpack 5는 특히 빌드 시간 및 번들 효율성 측면에서 Webpack 4에 비해 크게 개선

Unit & E2E & Integration Test

  • Unit Test

    • 응용 프로그램의 개별 부분을 격리하여 테스트하는 데 중점
      • 일반적으로 단일 함수 또는 컴포넌트
// > 두 숫자의 합을 올바르게 계산하는지 확인 <

// add.js
function add(a, b) {
    return a + b;
}

module.exports = add;
// add.test.js
const add = require('./add');

test('adds 1 + 2 to equal 3', () => {
    expect(add(1, 2)).toBe(3);
});

  • Integration Test

    • 다양한 모듈 또는 서비스 간의 상호 작용 테스트
    • 같이 애플리케이션의 여러 부분이 함께 작동하는 방식을 확인
      • 테스트할 API 엔드포인트가 있다고 가정
// > 엔드포인트에 HTTP 요청을 하고 응답이 예상대로 수행되는지 확인 <

// app.js
const express = require('express');
const app = express();

app.get('/sum', (req, res) => {
    const { a, b } = req.query;
    res.json({ sum: parseInt(a) + parseInt(b) });
});

module.exports = app;
// app.test.js
const request = require('supertest');
const app = require('./app');

test('GET /sum adds two numbers', async () => {
    const response = await request(app).get('/sum?a=1&b=2');
    expect(response.statusCode).toBe(200);
    expect(response.body.sum).toBe(3);
});

  • E2E Test

    • End To End Test
    • 실제 사용자 시나리오를 시뮬레이션하여 애플리케이션 전체를 테스트
// > 웹 응용 프로그램에서 로그인 프로세스를 테스트하는 것 <

// E2E test with Cypress
describe('Login Test', () => {
    it('successfully logs in', () => {
        cy.visit('/login'); // Visit the login page
        cy.get('input[name=username]').type('user123'); // Enter username
        cy.get('input[name=password]').type('password123'); // Enter password
        cy.get('button[type=submit]').click(); // Click the login button

        cy.url().should('include', '/dashboard'); // Ensure the user is redirected to the dashboard
    });
});

  • 결론
    • 단위 : 개별 컴포넌트를 격리하여 테스트
    • 통합 : 응용 프로그램의 여러 부분이 올바르게 작동하는지 확인
    • E2E : 사용자의 관점에서 전체 애플리케이션 워크플로를 검증

Debounce & Throttle & rAF

  • Debounce
    • 함수가 호출되는 속도를 제한하는 기술
    • 함수가 너무 자주 호출되지 않도록 하려는 경우에 유용

    • 프로세스
      • 함수를 실행하기 전에 마지막 호출
      • 일정 시간이 경과할 때까지 기다리기
function debounce(func, delay) {
    let inDebounce;
    return function() {
        const context = this;
        const args = arguments;
        clearTimeout(inDebounce);
        inDebounce = setTimeout(() => func.apply(context, args), delay);
    };
}

// Usage
window.addEventListener('resize', debounce(() => {
    console.log('Resize event handler called');
}, 250));

  • Throttle
    • 제한은 함수가 지정된 기간 동안 최대 한 번 호출
    • 함수의 속도 제한 실행에 유용
function throttle(func, limit) {
    let inThrottle;
    return function() {
        const args = arguments;
        const context = this;
        if (!inThrottle) {
            func.apply(context, args);
            inThrottle = true;
            setTimeout(() => (inThrottle = false), limit);
        }
    };
}

// Usage
window.addEventListener('scroll', throttle(() => {
    console.log('Scroll event handler called');
}, 1000));

  • requestAnimationFrame
    • 다시 그리기 전에 애니메이션을 업데이트 위해 지정된 함수를 호출

    • 프로세스
      • 애니메이션을 수행하려는 것을 브라우저에 알리기
      • 브라우저가 다음 다시 그리기 전에 애니메이션을 업데이트 위해 지정된 함수를 호출
let lastScrollY = 0;

function onScroll() {
    lastScrollY = window.scrollY;
    requestAnimationFrame(update);
}

function update() {
    console.log('Scroll position:', lastScrollY);
    // Perform updates based on scroll position
}

window.addEventListener('scroll', onScroll);

Debounce 및 throttle은 모두 이벤트 처리기가 호출되는 속도를 제어하는 데 효과적

특히 스크롤 이벤트에 연결된 경우 부드러운 애니메이션 및 업데이트에 이상적


Chakra UI 사용

  • 적절한 경우 React.memo, useMemo, useCallback과 같은
    성능 최적화 기술을 사용

  • 자신만의 색상, 글꼴 및 기타 스타일 속성을 정의하기 위해
    사용자 정의할 수 있는 테마 개체를 제공


React 와 Next 차이

  • React는 UI 컴포넌트 구축에 중점을 둔 라이브러리
  • Next.js 는 React를 기반으로 구축된 프레임워크로 애플리케이션 개발을 위한 추가 기능과 구조를 제공

  • Next.js 는 React에 내장되어 있지 않은 SSR과 SSG를 기본적으로 지원
  • SEO 와 성능이 중요한 응용 프로그램에 더 적합

  • React 자체는 라우팅 기능을 제공하지 않음
  • 종종 React Router와 같은 타사 라이브러리에 의존
  • Next.js 내장 파일 기반 라우터가 포함

  • React 프로젝트는 웹팩 구성, Babel 설정 및 라우팅과 같은 기능에 대한 수동 설정이 필요
  • Next.js 이 구성의 많은 부분을 추상화하여 보다 통합된 환경을 제공

Next.js 에서 API는?

  • Next.js 애플리케이션 내에서 직접 서버 측 논리 및 API 경로를 작성 가능
  • API 엔드포인트로서의 서버리스 기능
  • pages/api 디렉토리에 작성
  • Node.js 환경
    • API 경로는 Node.js 환경에서 실행
    • 즉, 데이터베이스 연결, 양식 데이터 처리
    • 다른 API와의 통합과 같은 기능에서 직접 서버 측 코드를 작성

  • Express.js 또는 Koa와 같은 독립 실행형 서버 솔루션은 아님
profile
일단 한다

0개의 댓글