[기술면접] React 부분 2

Boyoung Lee·2024년 12월 16일

기술면접

목록 보기
35/49
post-thumbnail

<목차>

  1. useEffect가 2번 실행되는 경우
  2. 커스텀 훅
  3. React.memo

4. useEffect가 2번 실행되는 경우

  • React 18 버전부터 개발 모드에서 useEffect가 두번 실행되는 현상 관찰
  • Strict Mode 활성화
  • 자동으로 컴포넌트를 두 번 마운트하고 언마운트하는 동작 때문
    1. 부수 효과 감지
    • 부수효과를 더욱 안정적으로 감지하고 의도치 않은 부수효과가 발생하지 않도록 설계
    • 개발자가 코드의 버그를 더 쉽게 발견, 수정
    1. 상태 관리 오류 방지
    • 비정상적으로 초기화되거나 업데이트되는 문제를 조기 발견
    • 애플리케이션의 안정성 향상
    1. 메모리 누수 감지
    • 컴포넌트가 언마운트된 후에도 남아 있는 이벤트 리스너나 타이머 같은 리소스를 정리하지 않는 경우 메모리 누수 발생
    • 이중렌더링을 통해 이러한 문제를 더욱 명확하게 식별
  • 이 동작은 오직 개발 모드에서만 적용
  • 프로덕션 빌드에서는 useEffect는 한 번만 실행
  • 리액트가 의도한 동작

Q. 리액트의 개발 서버에서는 useEffect가 2번 실행되는 모습이 관찰되는데요. 그 이유가 무엇일까요?

5. 커스텀 훅

  • 리액트에서 제공하는 기본 훅을 조합하여 사용자가 직접 만든 재사용 가능 함수
  • 커스텀 훅은 특정 로직을 모듈화 하여 여러 컴포넌트 간에 공유하고 재사용할 수 있도록 도움
  • 코드의 중복을 축소
  • 코드 가독성 향상
  • 관심사 분리 촉진

사용 사례

  1. 데이터 페칭
  • API로부터 데이터를 가져오고, 로딩 상태와 에러를 관리하는 로직을 커스텀 훅으로 추출
  • 다양한 컴포넌트에서 API 호출 로직을 재사용 가능
  1. 폼 입력 관리
  • 사용자 입력과 폼 검증 로직을 커스텀 훅으로 관리 가능
  • 여러 폼 컴포넌트에서 유사한 로직을 쉽게 재사용 가능
  1. 이벤트 리스너
  • 윈도우나 특정 요소에 이벤트 리스너를 추가하고 제거하는 로직을 커스텀 훅으로 작성
  • 이벤트 관리 쉽게 가능
  1. 컨텍스트와 상호작용
  • 리액트의 컨텍스트를 사용하여 테마 설정이나 사용자 인증 상태 같은 앱 전반의 상태를 관리하는 로직을 커스텀 훅으로 만들 수 있음
  • 코드의 중복 방지

커스텀 훅과 유틸의 차이

  • 커스텀 훅 (Custom Hook)

    • 리액트의 훅 API(useState, useEffect, useContext등)를 활용하여 만든 재사용 가능 함수
    • 컴포넌트 로직 (상태 관리, 사이드 이펙트 처리 등)을 모듈화하고 여러 컴포넌트 간 공유
    • 리액트의 상태나 생명주기 기능에 직접적으로 연결되어 있기 때문에 컴포넌트 내부에서만 사용 가능
  • 유틸리티 함수 (Utilities)

    • 특정한 작업을 수행하는 순수 함수
    • 애플리케이션 전반에서 사용
    • 어떠한 외부 상태에도 의존하지 않음
    • 주어진 입력에 대해서만 결과 반환
    • 리액트의 특정 기능과는 독립적이라 리액트 외부에서도 사용 가능
  • 차이점

    • 사용 범위의 차이 : 커스텀 훅은 리액트 컴포넌트 내에서만 사용. 리액트의 훅 API와 상태 관리 기능을 활용 가능. 유틸리티 함수는 어떤 자바스크립트 환경에서나 사용될 수 있으며, 리액트의 컴포넌트 생명주기나 상태와는 독립적

    • 기능: 커스텀 훅은 리액트의 상태 관리, 사이드 이펙트 관리 등에 사용. 유틸리티 함수는 데이터 포맷팅, 계산 로직, 배열 조작 등의 일반적인 작업에 사용.

서비스 레이어와 커스텀 훅의 차이

  • 서비스 레이어 (auth.service.ts):
    • 주로 순수 JavaScript 또는 TypeScript 함수를 사용하여 데이터르 ㄹ처리
    • API 호출 등 로직을 캡슐화
    • 리액트의 컴포넌트 라이프사이클이나 상태에 독립적으로 작용
    • 리액트 외 환경에서도 사용 가능
      ex) 인증 토큰 관리, 로그인 및 로그아웃 처리, 사용자 세션 관리 등의 기능 수행

API 호출 로직

// auth.service.ts
import axios from 'axios';

export const login = async (username: string, password: string) => {
  const response = await axios.post('/api/login', { username, password });
  if (response.data) {
    localStorage.setItem('user', JSON.stringify(response.data));
  }
  return response.data;
};

export const logout = () => {
  localStorage.removeItem('user');
};
  • 커스텀 훅 (예: useAuth):
    • 리액트의 useState, useEffect, useContext 등의 훅을 활용하여 컴포넌트의 상태 및 사이드 이펙트를 관리
    • 컴포넌트와 밀접한 연관
    • 리액트 컴포넌트 내에서만 사용
      ex) auth.service.ts에서 정의된 함수를 호출하고, 그 결과를 컴포넌트의 상태로 관리하거나 컴포넌트에 필요한 사이드 이펙트를 처리하는 데 사용될 수 있음

서비스 레이어를 사용하여 컴포넌트의 상태를 관리하는 로직

// useAuth.js
import { useState, useEffect } from 'react';
import * as AuthService from './auth.service';

function useAuth() {
  const [user, setUser] = useState(null);

  useEffect(() => {
    const storedUser = JSON.parse(localStorage.getItem('user'));
    if (storedUser) {
      setUser(storedUser);
    }
  }, []);

  const login = async (username, password) => {
    const userData = await AuthService.login(username, password);
    setUser(userData);
  };

  const logout = () => {
    AuthService.logout();
    setUser(null);
  };

  return { user, login, logout };
}

export default useAuth;

=> auth.service.ts는 데이터를 관리하고 처리하는 비즈니스 로직을 캡슐화하는 반면, useAuth 같은 커스텀 훅은 이러한 서비스 로직을 리액트 컴포넌트에서 사용할 수 있도록 상태 관리와 연동시키는 역할

Q. 커스텀 훅을 사용해보셨나요? 사용해본 경험을 이야기해주세요.

6. React.memo

  • 리액트에서 제공하는 고차 컴포넌트
  • 컴포넌트의 렌더링 성능을 최적화하기 위해 사용
  • 불필요한 렌더링을 방지하는데 효과적
  • 컴포넌트의 props가 변경되지 않았다면 리렌더링 생략
  • 마지막으로 렌더링된 결과를 재사용함

작동원리

  • 컴포넌트로 전달되는 props가 변경되었는지 여부를 얕은 비교를 통해 판단.
  • 얕은 비교는 객체의 최상위 수준의 프로퍼티만 비교

예시

import React from 'react';

const MyComponent = React.memo(function MyComponent(props) {
  // 컴포넌트 로직
  console.log("Rendering");
  return <div>{props.children}</div>;
});

주의할 점

  • 모든 컴포넌트에 무분별하게 사용되어서는 안됨
  • 비교 함수의 복잡성이나 오버헤드가 성능 이득을 상쇄할 수 있기 때문
  • 실제로 성능 문제가 있는 컴포넌트에 대해서만 적용하는게 좋음
  • 얕은 비교를 수행하므로 객체나 배열과 같은 복잡한 자료형 props를 사용할 때는 커스텀 비교 함수의 정의가 필요

Q. 리액트 컴포넌트의 렌더링 성능 향상에 쓰이는 React.memo에 대해 설명해주세요.

profile
정리정돈을 잘하는 개발자가 꿈

0개의 댓글