Skip to content

useState 제대로 알고 사용하자!!! #18

@sernan96

Description

@sernan96

useState가 뭔지??

일단 useState는 리액트 공식 레퍼런스에 이렇게 정의되어 있다
useState는 컴포넌트에 state 변수를 추가할 수 있는 React Hook입니다.

[something, setSomething]이런 구조로 선언하는 것이 규칙인데 이를 배열 구조 분해라고 하는데 직역이라 뭔가 어색하다.
something이라는 상태를 setSomething이라는 _modifier_로 상태를 변경해줄 수 있다.

useState에 대해서 간단한 소개를 마치고 이번에 이슈를 작성하게 된 이유에 대해서 먼저 말하자면
useState에서 배열을 state로 줄때 이 배열을 수정하기 위해선 기존의 배열에 추가하면 반영이 되지 않는다.
그래서 배열에 새로운 원소를 주거나 뺄때는 기존의 배열을 복사하여 수정을 하고 이를 setState를 통해 전달해주어야
제대로 된 반영이 이루어진다.

예시 코드

function handleClick() { setAge(age + 1); setAge(age + 1); setAge(age + 1); }
age가 42라고 가정했을 때 3번 1씩 더해줬으니 45가 나와야 정상이지만 43이 나온다.

..? 이유가 무엇일까 ..?
이는 set 함수를 호출해도 이미 실행 중인 코드에서 age state 변수가 [업데이트되지 않기] 때문이다.
따라서 각 setAge(age + 1) 호출 3번은 setAge(43) 3번을 한 것이 됩니다.

이거로도 사실 충분하지만 좀 더 자세히 알고싶어서 Chat-GPT의 답과 공식 레퍼런스 문서에 적힌 내용이 대동소이했는데 요약해서 적어보자면

React의 상태는 불변성을 유지해야 한다.

  1. 참조(레퍼런스) 비교:
  • React는 상태가 변경되었는지를 빠르게 확인하기 위해 얕은 비교(shallow comparison)를 사용합니다. 얕은 비교는 객체의 참조가 변경되었는지를 확인한다.

  • 만약 기존 배열에 직접적으로 요소를 추가하거나 제거하면(예: push, pop 사용) 배열의 참조는 변경되지 않으므로 React는 상태가 변경되었음을 감지하지 못한다.

  1. 불변성(Immutability):
  • 불변성을 유지하면 상태의 이전 값과 새로운 값을 쉽게 비교할 수 있으며, 이는 상태 관리와 디버깅을 용이하게 합니다.
  • 새로운 배열을 생성하여 상태를 변경하면, React는 참조가 변경된 것을 인식하고 컴포넌트가 리렌더링됩니다.

해결 방법

배열 상태를 변경할 때는 기존 배열을 수정하지 않고 새로운 배열을 생성하여 setState 함수를 호출해야 함. 이를 위해 JavaScript의 map, filter, concat, 스프레드 연산자([...]) 등을 사용할 수 있다.

내가 위에 작성했던 예시코드의 해결법은 아래와 같다.
*javascript function handleClick() { setAge(a => a + 1); // setAge(42 => 43) setAge(a => a + 1); // setAge(43 => 44) setAge(a => a + 1); // setAge(44 => 45) }

알아야 힘이다!.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions