[React] React Hooks란?

복숭아는딱복·2024년 7월 20일

React

목록 보기
3/7
post-thumbnail

React Hooks란 무엇인가?

React Hooks는 ReactConf 2018에서 발표된 class 없이 state를 사용할 수 있는 새로운 기능이다.
Hooks를 사용하면 클래스 컴포넌트를 작성하지 않고도 상태 관리와 기타 React 기능을 사용할 수 있다.

React Hooks가 필요한 이유

React Hooks는 클래스 컴포넌트로 사용되면서 느꼈던 불편함이나 문제들을 해결하기 위해 등장했다.
원래 React는 주로 클래스 컴포넌트를 사용하고 React Hooks는 함수형 컴포넌트를 사용한다. React Hooks를 사용하면 함수형 컴포넌트에서도 강력한 상태 관리와 생명주기 메서드를 활용할 수 있어 현대적인 리액트 개발에서 많이 사용되고 있다.

  • 클래스 컴포넌트: 초기의 리액트 컴포넌트 방식. 더 많은 기능을 제공하지만 성능이 느림
  • 함수형 컴포넌트: 2018년 이후 등장. React Hooks 사용 가능. 더 적은 기능을 제공하지만 더 빠른 성능 제공

그렇다면 함수형 컴포넌트에서 더 적은 기능을 제공하는데, 어떤 기능을 쓸 수 없는 것 일까?

리액트 생명주기

출처 : https://projects.wojtekmaj.pl/react-lifecycle-methods-diagram/

함수형에서 못 쓰는 것은 리액트 생명주기다. 리액트를 실행하고 업데이트하고 멈추는 중요한 생명주기를 함수형에서는 못 사용했기 때문에 함수형이 더 빠르고 간결하더라도 클랙스형을 써왔지만, 2018년 이후 Hooks가 등장하면서 생명주기 부분을 대체할 수 있게 되었다.

React Hooks 종류

useState

상태 변수를 선언하고, 상태를 갱신할 수 있는 함수와 함께 반환한다. 초기 상태를 인수로 받아들인다.

import React, { useState } from 'react';

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

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

useEffect

기본적으로 컴포넌트가 마운트, 업데이트, 언마운트 될 때 호출된다. 인수로 배열을 받아 특정 값이 변경될 때만 실행되도록 할 수 있다.

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

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

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

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

useContext

컨텍스트(Context)를 사용하여 트리 내에서 데이터를 전역적으로 공유할 수 있다.

import React, { useContext } from 'react';

const MyContext = React.createContext();

function MyComponent() {
  const value = useContext(MyContext);
  return <div>{value}</div>;
}

function App() {
  return (
    <MyContext.Provider value="Hello, World!">
      <MyComponent />
    </MyContext.Provider>
  );
}

useReducer

상태 로직을 컴포넌트 외부로 이동시켜 복잡한 상태 관리를 수행할 때 유용하다. Redux와 유사한 패턴을 따른다.

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>
  );
}

useMemo

성능 최적화를 위해 메모이제이션된 값을 반환. 특정 값이 변경될 때만 계산을 수행하도록 할 수 있다.

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

function ExpensiveComponent({ input }) {
  const computeExpensiveValue = (input) => {
    // ... 비용이 큰 계산 ...
    return input * 2;
  };

  const expensiveValue = useMemo(() => computeExpensiveValue(input), [input]);

  return <div>{expensiveValue}</div>;
}

useCallback

메모이제이션된 콜백 함수를 반환. 컴포넌트가 리렌더링될 때 동일한 함수 인스턴스를 유지하도록 한다.

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

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

  const increment = useCallback(() => {
    setCount((c) => c + 1);
  }, []); // 빈 배열을 전달하여 함수가 최초 렌더링 시에만 생성되도록 함

  return (
    <div>
      <p>Count: {count}</p>
      <button onClick={increment}>Increment</button>
    </div>
  );
}

0개의 댓글