잡다로그

[React.js] Hook소개, useState, useEffect 본문

Web/React

[React.js] Hook소개, useState, useEffect

날으는다람쥐 2024. 7. 29. 13:45

👋🏻Hook 소개

Hook은 함수 컴포넌트에서 React state와 생명주기 기능(lifecycle features)을 “연동(hook into)“할 수 있게 해주는 함수이다.


문제 배경: 

  • React 프로젝트에서는 상태 관련 로직들과 사이드 이펙트( React 컴포넌트 안에서 데이터를 가져오거나 구독하고, DOM을 직접 조작하는 작업 )가 있는 컴포넌트들을 유지보수 해야 한다.

문제와 해결의 한계: 

  • 이 때 사용되는 각 생명주기 메서드에는 자주 관련 없는 로직이 섞여들어 버그가 쉽게 발생하고, 쉽게 무결성을 해치게 된다. React와 상태 관리 라이브러리를 함께 결합해서 사용해왔지만, 이는 종종 너무 많은 추상화를 하고, 컴포넌트 재사용을 더 어렵게 만든다.

Hook의 등장:

  • 이를 해결하기 위해, 생명주기 메서드를 기반으로 쪼개기 보다 Hook을 통해 서로 비슷한 것을 하는 작은 함수의 묶음으로 컴포넌트를 나누는 방법을 사용할 수 있다. 

Hook의 특징:

  • Hook은 컴포넌트로부터 상태 관련 로직을 추상화하여, 독립적인 테스트와 재사용이 가능해진다.
  • Hook은 계층의 변화 없이 상태 관련 로직을 재사용할 수 있도록 도와준다.
  • Hook은 React 16.8 부터 추가된 기능으로, Class 없이도 State와 다른 React의 기능들을 사용할 수 있게 해준다.

✌️ Hook 사용 규칙

Hook은 그냥 JavaScript 함수이지만, 두 가지 규칙을 준수해야 한다.

  1. 최상위에서만 Hook을 호출한다. 반복문, 조건문, 중첩된 함수 내에서 Hook을 실행하면 안된다.
  2. 함수 컴포넌트 내에서만 Hook을 호출해야 한다. 

📌State Hook

useState

useState는 함수형 컴포넌트에서 상태(state)를 관리하기 위해 사용한다. state는 컴포넌트의 랜더링과 재랜더링을 트리거하며, 동적인 데이터를 관리할 수 있게 한다.

state의 초기 값을 인자로 받고, 변수와 해당 변수를 갱신할 수 있는 함수 두 가지 쌍을 반환한다. 

import React, { useState } from 'react';

function Example() {
  // "count"라는 새 상태 변수를 선언합니다
  const [count, setCount] = useState(0);

  return (
    <div>
      <p>You clicked {count} times</p>
      <button onClick={() => setCount(count + 1)}>
        Click me
      </button>
    </div>
  );
}

이 state는 컴포넌트가 다시 렌더링 되어도 그대로 유지된다. 

 

useState는 현재의 state값과 이 값을 업데이트 하는 함수를 쌍으로 제공한다. 이 함수를 다른 곳에서 호출해서 state값을 변경할 수 있다. 이는 Javascipt Class의 this.setState와 거의 유사하지만, useState Hook의 state는 객체일 필요가 없다는 점에서 차이가 있다

 

값을 업데이트 하는 방법에는 1) updater 함수를 사용 2) 직접 다음 값 전달 이 있다. 현재 상태에 기반한 여러 번의 업데이트가 필요한 상황에서는 updater 함수를 사용하는 것이 좋다.

const [age, setAge] = useState(42);

// 직접 값 전달
function handleClick() {
  setAge(age + 1); // setAge(42 + 1)
  setAge(age + 1); // setAge(42 + 1)
  setAge(age + 1); // setAge(42 + 1)
}

// updater 함수 사용
function handleClick() {
  setAge(a => a + 1); // setAge(42 => 43)
  setAge(a => a + 1); // setAge(43 => 44)
  setAge(a => a + 1); // setAge(44 => 45)
}

 

상태에 객체와 배열을 넣고 업데이트 하기 위해서는 직접 값을 변경하지 말고, 전체 값을 복사한 뒤 새로운 상태로 업데이트해야 한다. 

// 🚩 이런 식으로 state의 객체를 변경하면 안된다:
form.firstName = 'Taylor';

// ✅ 새로운 객체로 상태를 대체해야 한다.
setForm({
  ...form,
  firstName: 'Taylor'
});

 

중복 배제 원칙에 따라, state 변수는 최소한이어야 한다. 다음과 같은 기준을 통해 state 로 사용할 것인지 말 것인지 결정할 수 있다.

• 부모로부터 Props를 통해 전달됩니까? 그러면 확실히 state가 아닙니다.

• 시간이 지나도 변하지 않나요? 그러면 확실히 state가 아닙니다.

• 컴포넌트 안의 다른 state나 Props를 가지고 계산 가능한가요? 그렇다면 state가 아닙니다.

⚡Effect Hook

useEffect

useEffect는 컴포넌트를 외부 시스템(네트워크나 브라우저 API, 라이브러리들)과 연결할 수 있게 해주는 React 훅이다. 컴포넌트가 랜더링될 때와 state 또는 props가 변경될 때 수행되어야 하는 side effects를 처리하기 위해 사용된다.

 

Effects는 컴포넌트 안에 선언되어있기 때문에 props와 state에 접근할 수 있다. 기본적으로 React는 매 렌더링 이후에 effects를 실행한다. 

import { useEffect } from 'react';
import { createConnection } from './chat.js';

function ChatRoom({ roomId }) {
  // setup
  const [serverUrl, setServerUrl] = useState('https://localhost:1234');

  useEffect(() => {
    const connection = createConnection(serverUrl, roomId);
    connection.connect();
    return () => {
      connection.disconnect();
    };
  }, [serverUrl, roomId]); // [dependencies]
  // ...
}

useEffect에는 2개의 인수가 필요한데, 

1. 외부 시스템과 컴포넌트를 연결하는 설정코드가 포함된 설정 함수

const connection = createConnection(serverUrl, roomId);
connection.connect();

외부 시스템과 연결을 해제하는 정리코드가 포함된 정리함수도 반환할 수 있다.

return () => {
  connection.disconnect();
};

그리고 2. 함수 내부에서 사용하는 값들을 포함하는 의존성 배열 이 필요하다.

}, [serverUrl, roomId]);

✔️실행 단계

  • 컴포넌트가 화면에 추가(마운트 시)되면 React는 설정 함수를 실행한다. 
  • 의존성이 변경된 후 다시 렌더링할 때마다,
    React는 먼저 기존의 props와 state로 정리 함수를 실행한 다음,
    새로운 props와 state값으로 설정 함수를 실행한다. 
  • 컴포넌트가 화면에서 제거(마운트 해제)되면 React는 정리 함수를 실행한다.

외부 시스템과의 연결 예시에는 아래와 같은 것들이 있다.

  1. 채팅 서버와 연결
  2. 전역 브라우저 이벤트 감시
  3. 애니메이션 동작시키기
  4. 모달 대화 상자 제어하기
  5. 요소의 가시성 추적

https://ko.react.dev/reference/react/useState

 

useState – React

The library for web and native user interfaces

ko.react.dev

 

https://react.dev/reference/react/useEffect#fetching-data-with-effects

 

useEffect – React

The library for web and native user interfaces

react.dev

 

Comments