요약
- const [state, setState] = useState(initialState);
- useState는 상태를 관리할 수 있는 React 훅
- 상태 업데이트는 비동기적, 일괄적으로 처리
- 상태값이 바뀌지 않으면 렌더링이 발생하지 않음
- 상태 초기값으로 함수나 복잡한 계산식을 넣을 경우 함수 자체를 선언
useState란?
React에서 'useState'는 상태를 정의하고 관리할 수 있게 해주는 훅(Hook)이다.
'useState'는 두 개의 요소를 가진 배열을 반환한다.
사용법
const [state, setState] = useState(initialState);
- state: 현재 상태 값(읽기 전용으로 간주)
- setState: 상태 값을 업데이트하고 컴포넌트를 다시 렌더링할 수 있게 해주는 set 함수
- initialState: 상태의 초기값
useState의 반환값은 배열이며, 관례적으로 배열 분해를 사용하여 상태 변수와 업데이트 함수를 정의한다.
최초 렌더링 때 초기상태를 저장하고 다음 렌더링부터 무시하며,
초기값을 선언하지 않으면 'undefined'로 초기화한다.
useState 반환값 예시
console.log(useState()) // ['undefined', f]
주요 특징
1. 초기값 재생성 방지
React는 초기 상태를 한번 저장하고 다음 렌더링에서 무시한다.
그런데 초기 상태에 함수를 호출하면 계속 실행이 발생할 수 있다.(낭비 발생)
이 문제를 해결해결 하려면 함수의 값이 아닌 함수 자체를 초기값으로 선언해야한다.
// 👍 최초 렌더링에만 "initializing..." 출력
const initialCount = () => {
console.log("initializing...");
return 0;
};
const [count, setCount] = useState(initialCount);
// 🚩 렌더링 마다 "initializing..." 출력
const initialCount = () => {
console.log("initializing...");
return 0;
};
const [count, setCount] = useState(initialCount());
2. 루프나 조건 내에서 호출 안됨
'useState'는 루프나 조건 내에서 호출할 수 없어 항상 컴포넌트의 최상위 레벨에서 호출해야한다.
3. 상태 업데이트
- 상태 업데이트는 비동기적으로 처리된다.
따라서 상태 업데이트한 직후에 값을 확인하면 변경되지 않은 상태로 보일 수 있다.
import React, { useState } from "react";
import "./styles.css";
export default function App() {
console.log("페이지 렌더링👍");
const [name, setName] = useState("Han");
const handleClick = () => {
console.log("setName 버튼 클릭👈");
setName("Noah");
console.log(name);
};
return (
<div className="App">
<h1>Hello {name}</h1>
<button onClick={handleClick}>setName Button</button>
</div>
);
}
첫 렌더링 | 클릭 이벤트 발생 |
![]() |
![]() |
![]() |
![]() |
- 페이지 첫 렌더링 때 naem은 "Han"으로 초기화.(Hello Han 출력)
- setName Button 클릭 시 handlClick 함수 실행
- setName 버튼 클릭👈 콘솔이 출력되고 setName("Noah")로 상태 업데이트
- console.log(name)으로 로그를 찍어보면 "Han"이 출력되고 화면은 "Noah" 표시
업데이트 직후 확인시 업데이트 이전의 값을 보여준다.
- 상태 업데이트는 일괄처리 된다.
React는 상태 업데이트를 일괄처리하여 여러 번 렌더링하는 것을 방지한다.
따라서 아래와 같은 경우 최종 count 값이 1 이 된다.
setCount(count + 1); // setCount(0 + 1)
setCount(count + 1); // setCount(0 + 1)
setCount(count + 1); // setCount(0 + 1)
// 최종 count 값이 덮어써져 1이 된다.
setCount(c => c + 1); // setCount(0 + 1)
setCount(c => c + 1); // setCount(1 + 1)
setCount(c => c + 1); // setCount(2 + 1)
// 이전 상태 기반으로 계산하기 때문에 최종 count 값이 3이 된다.
일반적으로 업데이트 함수 인수의 이름은 해당 상태 변수의 첫 글자로 지정한다.
setCount(c => c + 1); // Count의 첫 글자 c
setLastName(ln => ln.reverse() // LastName 각 단어의 첫 글자 ln
- 상태 업데이트에 따른 렌더링
set함수로 상태를 업데이트하면 상태 저장 -> 렌더링 발생 -> UI 업데이트 가 된다.
그런데 현재 상태와 같은 값으로 업데이트하면 변화가 없기 때문에 렌더링이 발생하지 않는다.
import React, { useState } from "react";
import "./styles.css";
export default function App() {
console.log("페이지 렌더링👍");
const [name, setName] = useState("Noah");
const handleClick = () => {
console.log("setName 버튼 클릭👈");
setName("Noah");
};
return (
<div className="App">
<h1>Hello {name}</h1>
<button onClick={handleClick}>setName Button</button>
</div>
);
}
초기값이 "Noah"이고 버튼을 클릭하면 setName("Noah")를 한다.
처음 페이지가 렌더링되면서 "페이지 렌더링👍" 콘솔을 찍는다.
초기값과 업데이트하는 값이 같기때문에 버튼을 계속 클릭해도 "페이지 렌더링👍"이 나오지 않는 것을 볼 수 있다.
참고
React
React is the library for web and native user interfaces. Build user interfaces out of individual pieces called components written in JavaScript. React is designed to let you seamlessly combine components written by independent people, teams, and organizati
react.dev