리액트 훅(Hook)

찌끅·2024년 8월 14일

리액트 훅(Hook)

React에서 "훅(Hook)"은 함수형컴포넌트에서 상태와 생명주기 기능을 사용할 수 있게 해주는 기능이다. 혹은 클래스형 컴포넌트에서 사용할 수 있었던 기능을 함수형 컴포넌트에서도 활용할수 있게만들어졌다. React 16.8에서처음 도입되었으며, 가장 일반적으로사용되는 훅은 useStateuseEffect이다.

1. useState

useState는 컴포넌트 내에서 상태를 관리하는 데 사용된다. 함수형 컴포넌트 내에서 상태를 선언하고, 그 상태를 업데이트하는 데 필요한 함수를 반환한다.

예시:

import React, { useState } from 'react';

function Counter() {
  // count라는 상태 변수와 이를 업데이트할 setCount라는 함수 생성
  const [count, setCount] = useState(0);

  return (
    <div>
      <p>현재 카운트: {count}</p>
      <button onClick={() => setCount(count + 1)}>카운트 증가</button>
    </div>
  );
}

export default Counter;

위 코드에서 useState(0)count라는 상태 변수와 setCount라는 상태 업데이트 함수를 반환한다. count의 초기값은 0이며, 버튼을 클릭할 때마다 setCount 함수를 호출하여 상태를 업데이트한다.

3. useEffect

useEffect는 컴포넌트가 렌더링된 후에 부수 효과(side effects)를 수행하는데 사용된다. 부수 효과는 데이터 페칭, DOM 직접 조작,타이머 설정 등 다양한 작업을 포함한다. useEffect는 클래스 컴포넌트에서 componentDidMount, componentDidupdate, componentWillUnmount를 대체하는 기능을 수행한다.

예시:

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

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

  useEffect(() => {
    // 1초마다 count를 증가시키는 타이머 설정
    const timer = setInterval(() => {
      setCount((prevCount) => prevCount + 1);
    }, 1000);

    // 컴포넌트가 언마운트될 때 타이머를 정리(cleanup)
    return () => clearInterval(timer);
  }, []);

  return <div>타이머: {count}</div>;
}

export default Timer;

위 예시에서 useEffect는 컴포넌트가 처음 렌더링된 후 1초마다 count를 증가시키는 타이머를 설정한다. useEffect는 두 번째 인수로 빈 배열 []을 받았는데, 이는 이 효과가 처음에만 실행되고, 그 이후로는 실행되지 않음을 의미한다. useEffect는 또한 컴포넌트가 언마운트될 때 타이머를 정리하기 위한 함수를 반환한다.

3. useContext

useContext는 React에서 제공하는 Context API를 사용할 수 있게 해준다. 이를 통해 컴포넌트 트리 전체에 걸쳐 전역적인 데이터를 공유할 수 있다.

예시:

import React, { useContext } from 'react';

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

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

  return <div style={{ background: theme === 'light' ? '#fff' : '#333' }}>테마 적용</div>;
}

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

export default App;

위코드에서 useContext를 사용하여 ThemeContext의 현재 값을 가져온다. App 컴포넌트는 ThemeContext.Provider를 통해 하위 컴포넌트에 'dark' 값을 제공한다.

4. useReducer

useReduceruseState와 유사하지만, 복잡한 상태 로직을 처리하거나 상태 업데이트가 서로 의존적인 경우에사용된다. 리듀서는 현재 상태와 액션을 인수로 받아 새로운 상태를 반환하는 함수이다.

예시:

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:
      return state;
  }
}

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

  return (
    <div>
      <p>카운트: {state.count}</p>
      <button onClick={() => dispatch({ type: 'increment' })}>증가</button>
      <button onClick={() => dispatch({ type: 'decrement' })}>감소</button>
    </div>
  );
}

export default Counter;

이 예에서 useReducerreducer 함수와 초기 상태 initialState를 사용해 상태와 dispatch함수를 반환한다. dispatch 함수는 액션을 reducer에 전달하여 상태를 업데이트한다.

5. useRef

useRef는 컴포넌트에서 DOM 요소나 특정 값의 참조를 저장하고 유지하는 데 사용된다. 이 값은 컴포넌트의 생명주기 동안 변경될 수 있지만, 변경이 컴퓨넌트를 다시 렌더링하지는 않는다.

예시:

import React, { useRef } from 'react';

function FocusInput() {
  const inputRef = useRef(null);

  const handleFocus = () => {
    inputRef.current.focus();
  };

  return (
    <div>
      <input ref={inputRef} type="text" placeholder="텍스트 입력" />
      <button onClick={handleFocus}>포커스</button>
    </div>
  );
}

export default FocusInput;

6. useMemouseCallback

이 두 훅은 성능 최적화를 위해 사용된다.

  • useMemo는 메모이제이션된 값을 반환한다. 복잡한 ㅖ산 결과를 재사용하고자 할 때 사용된다.
  • usecallback은 메모이제이션된 콜백 함수를 반환한다. 동일한 함수가 여러 번 생성되는 것을 방지하여 성능을 최적화한다.

예시 (useMemo):

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

function ExpensiveCalculation({ num }) {
  const calculate = (n) => {
    console.log('복잡한 계산 중...');
    return n * 2;
  };

  const result = useMemo(() => calculate(num), [num]);

  return <div>결과: {result}</div>;
}

여기서 useMemonum이 변경될 때만 calculate 함수를 다시 실행하여 결과를 계산한다. 그 외의 경우에는 이전 결과를 재사용한다.

예시 (usecallback):

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

function Button({ onClick }) {
  console.log('버튼 렌더링');
  return <button onClick={onClick}>클릭</button>;
}

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

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

  return (
    <div>
      <Button onClick={handleClick} />
      <p>카운트: {count}</p>
    </div>
  );
}

이 코드에서 useCallback을 사용하면 handleClick 함수가 매번 새로 생성되지 않고 동일한 함수가 재사용된다. 이는 특히 하위 컴포넌트에 함수가 props로전달될 때 불필요한 렌더링을 방지할 수 있다.

결론

React의 훅은 함수형 컴포넌트에서 상태관리와 부수 효과 처리, 그리고 다양한 생명주기 관련 기능을 간편하게 사용할 수 있게 해준다. useState, useEffect는 가장 많이 사용되는 훅이며, useReducaer, useContext, useRef 등은 특정 상황에서 유용하게 사용될 수 있다. 각 훅의 역할을 이해하고 적절하게 사용하는 것이 React 애플리케이션을 효율적으로 개발하는 데 매우 중요하다.

0개의 댓글