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 |