I code, therefore I exist.

웹 프론트 엔드 개발을 공부하고 있는 Ocean이라고 합니다. 만나서 반갑습니다.

WEB/REACT

useState

Ocean 2024. 6. 16. 17:22

useState란?

useState는 컴포넌트에 state 변수를 추가할 수 있는 React Hook입니다.

const [state, setState] = useState(initialState);

 

state란 컴포넌트의 기억 저장소라고 합니다. React Component가 Rerendering 될 때, 특정한 상태를 기억해야 하는 경우가 많습니다. 이 때 일반 변수는 컴포넌트 함수가 실행, 즉 Render될 때 기존의 값을 초기화하기 때문에 React에서는 useState란 hook을 제공하여 state라는 개념을 통해서 React가 해당 Component의 state를 기억하게 하여, Component의 Rendering 사이의 데이터를 기억할 수 있게 합니다.

 

기본 규칙

useState는 컴포넌트의 최상위 레벨에서 호출하며, 매개변수로 state 초기 설정값을 지정합니다.

useState는 정확히 두 개의 값을 가진 배열을 반환합니다. 배열 구조 분해를 사용하여 사용자가 원하는 이름으로 설정할 수 있습니다.

import { useState } from 'react';

function MyComponent() {
  const [age, setAge] = useState(42);
  const [name, setName] = useState('Taylor');
  // ...

 

매개변수 1. 현재 state입니다. 첫 번째 렌더링 중에는 전달한 초기값과 일치합니다.

매개변수 2. state를 다른 값으로 업데이트하고 리렌더링을 촉발할 수 있는 set 함수입니다.

 

또한 useState는 조건문, 반복문 안에서는 호출할 수 없습니다.

https://pozafly.github.io/react/react-is-managing-hooks-as-an-array/

 

React는 Hooks를 배열로 관리하고 있다

왜 Hooks에 이런 제약 조건을 걸었을까? React 내부에서 Hooks를 어떻게 처리하고 있는지, 이렇게 디자인 된 이유는 무엇인지 알아보자.

pozafly.github.io

 

state 업데이트

function handleClick() {
  setName('Robin');
}

 

set 함수를 호출하면 다음 state('Robin')을 저장하고 새로운 값으로 컴포넌트를 다시 Rendering한 후 UI를 업데이트합니다.

만약 해당 state가 컴포넌트 내부에 UI로 사용되지 않더라도 state가 변경(set 함수가 동작하여 값이 변경)되면 Rerendering 됩니다.

 

함수형 업데이트, 업데이트 함수

function handleClick() {
  setAge(age + 1); // setAge(42 + 1)
  setAge(age + 1); // setAge(42 + 1)
  setAge(age + 1); // setAge(42 + 1)
}

 

React에서 setState 함수는 비동기적으로 동작합니다. 즉, 상태 업데이트는 즉시 발생하지 않으며, React가 다음 Rerendering 사이클에서 상태를 업데이트합니다. 이로 인해 여러 번의 상태 업데이트가 Batch 처리되어 위 코드는 setAge(age + 1)을 세 번 호출하지만, age state는 45가 아니라 43이 됩니다.

이 문제를 해결하려면 다음 state 대신 setAge에 업데이터 함수를 전달할 수 있습니다.

function handleClick() {
  setAge(a => a + 1); // setAge(42 => 43)
  setAge(a => a + 1); // setAge(43 => 44)
  setAge(a => a + 1); // setAge(44 => 45)
}

 

여기서 setAge에 콜백 함수로 들어가는 a => a + 1은 업데이터 함수입니다. 이 함수는 대기 중인 state를 가져와서 다음 state를 계산합니다. React는 업데이터 함수를 에 넣습니다. 그러면 다음 렌더링 중에 큐에 전달한 순서대로 호출하여 정상적으로 동작합니다.

 

업데이터 함수는 항상 사용해야 할까요? 꼭 그래야만 하는 것은 아닙니다. 대부분의 경우, 이 두 가지 접근 방식 사이에는 차이가 없습니다. React는 클릭과 같은 의도적인 사용자 액션에 대해 항상 다음 클릭 전에 age state 변수가 업데이트 되도록 합니다. 즉, 클릭 핸들러가 이벤트 핸들러를 시작할 때 “오래된” age를 볼 위험은 없습니다. 다만 동일한 이벤트 내에서 여러 업데이트를 수행하는 경우에는 업데이터가 도움이 될 수 있습니다. state 변수 자체에 접근하는 것이 어려운 경우에도 유용합니다. (리렌더링을 최적화할 때 이 문제가 발생할 수 있습니다). 매번 동작에 적확한 문법 보다는 일관성을 선호한다면 항상 업데이터 함수로 작성하는 것이 합리적일 것입니다.

 

초기 state를 함수로 초기화할 때

일반적으로 React는 초기 state를 한 번 저장하고 다음 렌더링부터는 이를 무시합니다.

function TodoList() {
  const [todos, setTodos] = useState(createInitialTodos());
  // ...

 

하지만 위와 같이 초기값을 함수를 호출하여 전달하면, 해당 컴포넌트가 매번 렌더링 될 때 마다 초기화 함수를 다시 실행합니다. 이는 큰 배열을 생성하거나 값비싼 계산을 수행하는 경우 낭비일 수 있습니다.

이 문제를 해결하기 위해서는 useState에 초기화 함수를 값으로 전달하면 됩니다.

function TodoList() {
  const [todos, setTodos] = useState(createInitialTodos);
  // ...

 

함수를 useState에 전달하면 React는 초기화 중에만 함수를 호출합니다.


해당 게시글은 아래의 링크를 정리한 글 입니다. 추가적인 정보가 필요하신 분들은 아래의 링크를 참고하세요. :)

https://ko.react.dev/reference/react/useState

 

useState – React

The library for web and native user interfaces

ko.react.dev

 

 

'WEB > REACT' 카테고리의 다른 글

useMemo  (0) 2024.06.19
useCallback  (0) 2024.06.18
useEffect  (0) 2024.06.18
useRef  (0) 2024.06.17
REACT란 무엇인가?  (0) 2023.07.08