githubEdit

State: 컴포넌트의 기억 저장소

일반 함수로 필요한 정보를 모두 저장할 수 없을 때

만약 지역변수로 index값을 관리하려고 할 경우, 재렌더링이 일어나지 않습니다. 또한 렌더링을 위해 새로고침을 하더라도 이전의 변경 사항은 고려하지 않고 초기화됩니다.

import { sculptureList } from './data.js';

export default function Gallery() {

  //지역변수로 index 변수 생성
  let index = 0;

  function handleClick() {
    //지역변수 값을 변경시키는 함수
    index = index + 1;
  }

  let sculpture = sculptureList[index];
  return (
    <>
      <button onClick={handleClick}>
        Next
      </button>
      <h2>
        <i>{sculpture.name} </i>
        by {sculpture.artist}
      </h2>
      <h3>
        ({index + 1} of {sculptureList.length})
      </h3>
      <img
        src={sculpture.url}
        alt={sculpture.alt}
      />
      <p>
        {sculpture.description}
      </p>
    </>
  );
}

따라서 이러한 문제를 해결해 줄 다른 방법이 필요합니다.

이를 위해 React는 useState 훅을 제공합니다.

useState()의 사용법

useState에는 다음과 같은 두가지 기능이 있습니다.

  1. 렌더링 간에 데이터를 유지하기 위한 state 변수.

  2. 변수를 업데이트하고 React가 컴포넌트를 다시 렌더링하도록 유발하는 state setter 함수

아까의 문제를 해결하기 위해서 먼저 파일 상단의 React에서 useState() 를 가지고 옵니다.

그리고 index값을 지역변수가 아닌 state값으로 바꿔줍니다.

useState는 항상 state의 현재 값과, state를 변환할 수 있는 함수를 반환하며, []를 이용한 배열 구조 분해arrow-up-right를 사용해 이 두가지의 반환값에 원하는 이름을 지정해주게 됩니다. 이때 const [something, setSomething]과 같이 지정하는 것이 규칙입니다.

useState()

이러한 useState() 는 무언가 기억하고 싶을 때 사용됩니다.

작동방식

  1. 컴포넌트가 처음 렌더링 됩니다. useState[초기값, set함수]를 반환합니다. React는 초기값을 최신 state 값으로 기억합니다.

  2. state를 업데이트합니다. 사용자가 버튼을 클릭하면 set함수를 호출합니다. 이는 React에 변화된 값이 state값임을 기억하게 하고 또 다른 렌더링을 유발합니다.

  3. 컴포넌트가 두 번째로 렌더링 됩니다. React는 여전히 useState(초기값)를 보지만, 변화된 값을 기억하고 있기 때문에 [변화된 값, set함수]를 반환합니다.

  4. 이런 식으로 계속됩니다.


useReducer()와 useState()

이때 재미있는 사실은 useState는 사실 useReducer로 구현됐다는 점입니다.

  • useReducer는 기본적으로 reducer와 초기값(initialState)을 받습니다.

  • 위 코드에서 reducer는 단순히 action을 반환하는 함수이며:

    • 기존 상태(state)는 무시하고, 새 값(action)으로 상태를 덮어쓰게 됩니다.

  • setState는 내부적으로 dispatch를 호출하여 새 값을 전달합니다.

만약 useReducer()로 useState()와 같이 동작하도록 작성한다면 아래와 같이 됩니다.

useStateuseReducer를 내부적으로 활용하여 구현된 간단한 버전이라고 할 수 있습니다.

컴포넌트에 여러 state 변수 지정하기

아예 상관없는 변수들은 분리해도 무관하나, 두 변수를 자주 함께 변경하는 경우에는 두 변수를 하나로 합치는 것이 좋습니다.

예를 들어, 필드가 많은 폼의 경우 필드별로 state 변수를 사용하는 것보다 하나의 객체 state 변수를 사용하는 것이 더 편리합니다.

Image

컴포넌트 내부에 State

State는 컴포넌트 인스턴스마다 완전히 격리된 state값을 가집니다.

Image

BrandLankBox 컴포넌트의 state는 각각 독립적인 값을 갖게 되고, 이를 이용해 하나의 컴포넌트를 중복해 사용할 수 있게됩니다.

useState의 한계점

리액트의 useState() 는 리액트가 만든 클로저 내부에서 관리되어 지역 상태로 생성되기 때문에 해당 컴포넌트에서만 사용할 수 있다는 단점이 있습니다. 하지만 그냥 전역 변수로 만들어서 관리할 경우 이는 작동하지 않습니다. 리렌더링을 일으키는 장치가 없기 때문입니다.

따라서 이를 위해서는 전역상태 라이브러리 사용이 필요합니다.

Last updated