본문 바로가기
카테고리 없음

리액트 훅(React Hooks)

by riversun1 2024. 5. 20.
 

리액트 훅(React Hooks)은

함수형 컴포넌트에서 상태(state)와 라이프사이클(lifecycle) 기능을 사용할 수 있게 해주는 기능입니다.

리액트 16.8 버전에서 도입되었으며, 클래스형 컴포넌트의 복잡성을 피하고,

함수형 컴포넌트의 장점을 살릴 수 있도록 돕습니다. 주요 훅은 다음과 같습니다:

 

1. useState

useState 훅은 컴포넌트에서 상태 변수를 선언할 수 있게 합니다.

import React, { useState } from 'react';

function Example() {
  const [count, setCount] = useState(0); // 초기 값 0

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

 

  • useState는 상태 변수와 이를 업데이트할 함수를 반환합니다.
  • 상태 변수의 초기값을 인자로 전달합니다.

 

 

2. useEffect

useEffect 훅은 컴포넌트가 렌더링된 이후에 수행될 작업을 설정할 수 있게 합니다.

import React, { useEffect, useState } from 'react';

function Example() {
  const [count, setCount] = useState(0);

  useEffect(() => {
    document.title = `You clicked ${count} times`;
  }, [count]); // count가 변경될 때마다 실행

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

 

  • useEffect는 사이드 이펙트를 수행하는 데 사용됩니다.
  • 두 번째 인자로 의존성 배열을 받아, 해당 배열에 있는 값이 변경될 때만 이펙트가 실행됩니다.
  • 빈 배열 []을 전달하면 컴포넌트가 처음 마운트될 때만 실행됩니다.
  • 반환값으로 클린업 함수를 제공하여 컴포넌트 언마운트 시 실행할 작업을 정의할 수 있습니다.

 

3. useContext

useContext 훅은 컨텍스트를 사용하여 컴포넌트 트리 전체에 걸쳐 값을 전달할 수 있게 합니다.

import React, { useContext } from 'react';

const ThemeContext = React.createContext('light');

function ThemedButton() {
  const theme = useContext(ThemeContext);

  return <button style={{ background: theme === 'dark' ? '#333' : '#fff' }}>I am styled by theme context!</button>;
}

function App() {
  return (
    <ThemeContext.Provider value="dark">
      <ThemedButton />
    </ThemeContext.Provider>
  );
}

 

 
  • useContext는 컨텍스트 객체를 인자로 받아 현재 컨텍스트 값을 반환합니다.

 

4. useReducer

useReducer 훅은 복잡한 상태 로직을 처리하거나, 상태가 여러 종류일 때 사용합니다. Redux의 reducer와 유사한 형태로 작동합니다.

import React, { useReducer } from 'react';

const initialState = { count: 0 };

function reducer(state, action) {
  switch (action.type) {
    case 'increment':
      return { count: state.count + 1 };
    case 'decrement':
      return { count: state.count - 1 };
    default:
      throw new Error();
  }
}

function Counter() {
  const [state, dispatch] = useReducer(reducer, initialState);

  return (
    <div>
      <p>Count: {state.count}</p>
      <button onClick={() => dispatch({ type: 'increment' })}>+</button>
      <button onClick={() => dispatch({ type: 'decrement' })}>-</button>
    </div>
  );
}

 

  • useReducer는 상태와 디스패치 함수를 반환합니다.
  • 복잡한 상태 관리를 단순화할 수 있습니다.

 

5. 커스텀 훅(Custom Hooks)

커스텀 훅은 여러 훅을 조합해 재사용 가능한 로직을 만들 수 있는 기능입니다.

import React, { useState, useEffect } from 'react';

function useFetch(url) {
  const [data, setData] = useState(null);

  useEffect(() => {
    fetch(url)
      .then(response => response.json())
      .then(data => setData(data));
  }, [url]);

  return data;
}

function DataComponent() {
  const data = useFetch('https://api.example.com/data');

  if (!data) return <div>Loading...</div>;

  return <div>{data.title}</div>;
}

 

  • 커스텀 훅은 use로 시작하는 이름을 가지며, 내부에서 다른 훅을 호출할 수 있습니다.
  • 복잡한 로직을 컴포넌트 외부로 추출해 코드 재사용성을 높일 수 있습니다.

 

이 외에도 useMemo, useCallback, useRef 등 다양한 훅이 있습니다.

useMemo, useCallback, useRef는 성능 최적화와 특정한 DOM 요소에 접근하는 등의 특수한 작업에 유용합니다.

각 훅의 사용법과 예제를 살펴보겠습니다.

 

 

1. useMemo

useMemo 훅은 값의 계산을 메모이제이션(Memoization)하여 성능을 최적화하는 데 사용됩니다. 특정 값이 변경될 때만 계산을 수행하여 불필요한 계산을 피할 수 있습니다.

import React, { useMemo, useState } from 'react';

function ExpensiveComponent({ num }) {
  const [count, setCount] = useState(0);

  const expensiveCalculation = (num) => {
    console.log('Calculating...');
    return num * 2;
  };

  const memoizedValue = useMemo(() => expensiveCalculation(num), [num]);

  return (
    <div>
      <p>Memoized Value: {memoizedValue}</p>
      <button onClick={() => setCount(count + 1)}>Re-render</button>
      <p>Count: {count}</p>
    </div>
  );
}

 

  • useMemo는 첫 번째 인자로 함수, 두 번째 인자로 의존성 배열을 받습니다.
  • 의존성 배열의 값이 변경될 때만 함수가 실행되고, 그렇지 않으면 이전 계산 값을 반환합니다.
  • 이는 특히 계산 비용이 높은 함수의 결과를 메모이제이션할 때 유용합니다.

 

2. useCallback

useCallback 훅은 함수를 메모이제이션하여 성능을 최적화하는 데 사용됩니다. 컴포넌트가 렌더링될 때마다 동일한 함수 인스턴스를 재사용할 수 있게 합니다.

import React, { useState, useCallback } from 'react';

function Button({ onClick }) {
  return <button onClick={onClick}>Click me</button>;
}

function ParentComponent() {
  const [count, setCount] = useState(0);
  const [text, setText] = useState('');

  const handleClick = useCallback(() => {
    setCount(count + 1);
  }, [count]);

  return (
    <div>
      <Button onClick={handleClick} />
      <input value={text} onChange={(e) => setText(e.target.value)} />
      <p>Count: {count}</p>
    </div>
  );
}

 

  • useCallback은 첫 번째 인자로 함수를, 두 번째 인자로 의존성 배열을 받습니다.
  • 의존성 배열의 값이 변경될 때만 새로운 함수 인스턴스를 생성하고, 그렇지 않으면 이전 함수를 반환합니다.
  • 이는 자식 컴포넌트에 콜백 함수를 전달할 때 유용하며, 불필요한 리렌더링을 방지할 수 있습니다.

 

3. useRef

useRef 훅은 DOM 요소나 클래스 컴포넌트 인스턴스에 접근하거나, 값이 변경되어도 리렌더링되지 않는 변수를 관리할 때 사용됩니다.

import React, { useRef, useEffect } from 'react';

function TextInputWithFocusButton() {
  const inputEl = useRef(null);

  const onButtonClick = () => {
    inputEl.current.focus();
  };

  return (
    <div>
      <input ref={inputEl} type="text" />
      <button onClick={onButtonClick}>Focus the input</button>
    </div>
  );
}

 

  • useRef는 초기 값을 인자로 받아, current 속성을 가진 객체를 반환합니다.
  • 반환된 객체는 컴포넌트의 전체 수명 동안 유지되며, DOM 요소에 접근할 때 유용합니다.
  • useRef로 관리하는 값은 변경되어도 컴포넌트를 리렌더링하지 않습니다.

 

4. useMemo, useCallback, useRef 비교

  • useMemo: 계산 비용이 높은 값을 메모이제이션하여 성능 최적화.
  • useCallback: 함수 인스턴스를 메모이제이션하여 자식 컴포넌트의 불필요한 리렌더링 방지.
  • useRef: DOM 요소에 접근하거나 컴포넌트가 리렌더링되어도 유지되는 값을 관리.

각 훅은 특정한 상황에서 성능 최적화와 코드의 효율성을 높이는 데 유용하며,

적절한 사용법을 이해하고 적용하는 것이 중요합니다.

 

 

 

 

각 훅은 각각 특정한 상황에서 유용하게 사용할 수 있습니다.

리액트 훅은 함수형 컴포넌트의 기능을 강화하고,

클래스형 컴포넌트의 복잡성을 줄이는 데 큰 기여를 하고 있습니다.