1 분 소요

useState

변화가 생겼을 때 컴포넌트 함수가 재실행되어야 한다는 것을 리액트에게 알려주는 방법
기본적으로 리엑트는 컴포넌트 함수 내부의 코드는 처음 렌더링될 때 한 번 실행되며, 일반적인 변수는 값이 변경되어도 리액트의 상태를 관리할 수 없고, useState 를 사용해야 UI를 업데이트를 할 수 있다.

📌 리액트에서 이전 상태 값을 기반으로 업데이트하는 이유?

리액트는 useState의 상태 업데이트를 비동기적으로 처리하기 때문에 상태가 즉시 반영되지 않아 예상치 못한 문제가 발생할 수 있다. 함수형 업데이트 방식은 이전 값(가장 최신 상태)을 기준으로 상태를 안전하게 업데이트한다.

const [isEditing, setIsEditing] = useState(false);

//이전 상태 기반 함수형 업데이트(setState에 새로운 값 대신 함수를 전달)
setIsEditing((prevIsEditing) => !prevIsEditing); //기대값 true, 결과값 true 일치
setIsEditing((prevIsEditing) => !prevIsEditing); //기대값 false, 결과값 false 일치

그렇다면 리액트에서는 왜 useState를 비동기적으로 처리하는가?

  • 리액트의 배칭(Batching)최적화 : 리액트에서 불필요한 렌더링을 방지하기 위해 여러 번의 상태 업데이트를 한 번의 렌더링으로 묶어서 처리하는 기법을 적용한다. → 즉, “여러 번 setState 호출해도 리렌더링 1번만 발생”
  • 렌더링의 일관성 유지 : 상태 변경이 즉시 반영되지 않고, 리액트가 상태 변경을 예약해 적절한 시점에 한번의 렌더링으로 처리

리액트에서 상태 변화의 스케줄을 조율한다?

✅ 리액트가 최적화된 방식으로 상태 업데이트를 관리하고, 성능을 고려해 변경을 한번에 처리한다는 의미

  1. setState를 호출
  2. 즉시 상태를 변경하는 것이 아니라, 리액트 내부에서 상태 업데이트를 예약
  3. 현재 실행 중인 코드가 끝날때 까지 대기
  4. 리액트가 한꺼번에 상태 변경을 처리하면서, 다시 렌더링을 실행
  5. 새로운 상태가 반영된 UI 업데이트

따라서 아래의 결과값이 기대값과 일치하지 않는 이유를 설명하면!
setState 는 비동기적으로 실행되기때문에 state 값이 즉시 업데이트되지 않고, 변경이 반영되지 않은 state를 직접 사용해 상태를 변경을 호출하면 초기값을 기준으로 계산되기 때문에 예상치 못한 결과가 나오는 것 !

const [isEditing, setIsEditing] = useState(false);

//현재 상태 값을 직접 참조 하기 때문에 모두 isEditing false인 시점을 기준으로 함
setIsEditing(!isEditing); //false의 반대값인 true로 설정 (하지만 아직 반영되지 않음)
setIsEditing(!isEditing); //기존 상태값 false를 참조하여 true로 설정

댓글남기기