Notice
Recent Posts
Recent Comments
관리 메뉴

즐겁게, 코드

useState 훅에 대하여 본문

🎨 프론트엔드/React.js

useState 훅에 대하여

Chamming2 2020. 12. 28. 00:07

리액트로 컴포넌트를 만들때 함수 컴포넌트를 사용하는 것이 대세가 된 지금 함수 컴포넌트에서 클래스 컴포넌트의 동작을 구현하는 훅(Hook)에 대한 이해는 필수적이다.

 

오늘은 리액트 훅의 기본적인 특징과 클래스 컴포넌트의 상태를 구현하는 useState 훅에 대해 알아보자.

import React, { useState } from "react";

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

  function decrementCount() {
    // count 가 들어간 부분을 재렌더링함.
    setCount((prevCnt) => prevCnt - 1);
  }

  function incrementCount() {
    // count 가 들어간 부분을 재렌더링함.
    setCount((prevCnt) => prevCnt + 1);
  }

  return (
    <>
      <button onClick={decrementCount}>-</button>
      <span>{count}</span>
      <button onClick={incrementCount}>+</button>
    </>
  );
}

export default App;

위는 클래스 컴포넌트의 상태와 setState 함수를 useState 훅으로 구현한 예제로 이렇게 훅을 사용하면 함수 컴포넌트에서 클래스 컴포넌트의 기능을 구현할 수 있다.

 

훅의 기본적인 특징으로는 클래스 컴포넌트의 동작을 함수 컴포넌트에 구현하는 것이 목적이므로 당연히 함수 컴포넌트에서만 사용이 가능하며 언제나 동일한 순서로 동작해야만 한다.

import React, { useState } from "react";

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

  if (count > 10) {
    const [bonus, setBonus] = useState(true);
  }

  function incrementCount() {
    setCount((prevCnt) => prevCnt + 1);
  }

  return (
    <>
      <span>{count}</span>
      <button onClick={incrementCount}>+</button>
    </>
  );
}

export default App;</pre

[위 코드는 에러를 출력합니다.]

 

따라서 이렇게 분기나 조건 내에 훅을 새롭게 정의하여 사용하는 것은 불가능하며, 위 코드는 카운터를 조작해 10점을 달성하면 bonus 라는 상태를 새로 생성하는 것처럼 보일 수도 있으나 실제로는 오류가 동작해 실행조차 불가능하다.

 

다양한 훅 중에서 처음 만나볼 리액트 훅은 useState으로, useState는 클래스 컴포넌트에서 사용하는 상태와 setState를 대체하는 쉬운 훅임에도 불구하고 종종 사용법을 헷갈릴 때가 있다.

 

[useState 훅의 기본 형태]

import React, { useState } from "react"

// 배열의 분해 할당 문법을 기억하자.
const [state, setState] = useState(0)

useState는 인자로 받은 값을 상태의 초깃값으로 삼고 언제나 초기 상태값과 업데이트 함수가 담긴 배열을 리턴한다.

즉 위의 코드에서는 state라는 변수에 초기 상태값 0을 저장하며 setState 함수를 통해 state 변수에 담긴 상태값을 변경할 수 있게 되는데, 이걸 이해하려면 리액트의 특성을 이해해야 한다.

 

리액트의 강점 중 하나는 상태값이 변경되면 가상 돔을 활용해 해당 상태값이 사용된 부분만을 다시 렌더링한다는 것이다.

그러나 업데이트 함수가 아닌 사용자가 임의로 상태값을 변경하면 리액트는 변경사항을 인식하지 못하고 재렌더링(re-render)을 수행하지 않아 화면의 값이 갱신되지 않는데, 따라서 상태값을 변경할 때는 반드시 업데이트 함수를 사용해야만 한다.

 

이번에는 수수께끼를 한번 풀어보자.

import React, { useState } from "react"

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

  function incrementCount() {
    setCount(count + 1)
    setCount(count + 1)
  }

  return (
    <>
      <span>{count}</span>
      <button onClick={incrementCount}>+</button>
    </>
  )
}

export default App

이렇게 카운터 코드가 있을 때 + 버튼을 누르면 count 상태값은 2씩 증가할까?

물론 이런 문제가 으레 그렇듯 답은 "No" 다.

 

리액트는 불필요한 재렌더링을 최대한 줄이기 위해 여러 개의 업데이트 함수를 한번에 처리하는데, 이 때 동일한 업데이트 함수가 존재할 때는 나중에 사용된 업데이트 함수의 인자로 상태를 변경한다.

 

만약 부득이하게 한 블럭 안에서 업데이트 함수가 여러 번 작동해야 한다면 다음과 같이 인자에 함수를 넣어줄 수도 있는데 이렇게 인자로 주어진 함수의 인자는 언제나 직전 상태값이 되어 버튼을 누르면 의도한 대로 2씩 숫자가 증가하게 된다.

import React, { useState } from "react";

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

  function incrementCount() {
    setCount((count) => count + 1);
    setCount((count) => count + 1);
  }

  return (
    <>
      <span>{count}</span>
      <button onClick={incrementCount}>+</button>
    </>
  );
}

export default App;

아마 이 부분이 useState를 사용할 때 가장 헷갈리는 부분일 텐데 업데이트 함수가 일괄적으로 상태를 업데이트하는 과정은 두 글을 읽어 보시는 것을 권해드립니다. (글 1) (글 2)

반응형

'🎨 프론트엔드 > React.js' 카테고리의 다른 글

useContext 훅에 대하여  (0) 2021.01.05
useRef 훅에 대하여  (1) 2021.01.01
useMemo 훅에 대하여  (0) 2020.12.30
Portal 사용하기  (0) 2020.12.28
useEffect 훅에 대하여  (1) 2020.12.28
Comments
소소한 팁 : 광고를 눌러주시면, 제가 뮤지컬을 마음껏 보러다닐 수 있어요!
와!! 바로 눌러야겠네요! 😆