[React] state 변경시 setState로 변경해야 하는 이유

김채운·2022년 10월 5일
2

React

목록 보기
10/24

state는 immutble(불변성)을 유지해야 하기 때문이다.
state는 컴포넌트 렌더링에 영향을 주는 데이터를 갖고 있는 객체인데, 이것을 업데이트 하기 위해서는 setState,useState가 필요하다. 직접 state를 수정하면 리액트는 render 함수를 호출하지 않아서 렌더링이 일어나지 않고 setState를 호출하여 state를 변경하면 리액트 엔진이 render 함수를 이용해서 렌더링을 실행하기 때문이다.

➡️ State란?

  • state는 변수이지만 우리가 알고있는 const,let과는 다르다.
  • state는 일반 변수와는 다르게 값이 바뀌면 렌더링이 일어난다. 즉, 값이 변하게 되면 연관있는 컴포넌트들이 다시 렌더링이 되면서 화면이 바뀌게 된다.
  • state는 props와 같이 컴포넌트 렌더링에 영향을 주는 데이터를 갖고 있는 객체이고, 컴포넌트 안에서 관리된다.

➡️ setState로 변경해야 하는 이유

  • setState는 state를 변경할 때 사용하는 함수이다.'

✔️ 컴포넌트는 현재의 this.state와 setState를 비교해서 업데이트가 필요한 경우에만 render함수를 호출하는데, state를 직접 수정하면 리액트가 render 함수를 호출하지 않아 상태 변경이 일어났는데도 렌더링이 일어나지 않을 수 있다. 상태 변경을 추적하고 변경에 따라 구성 요소를 다시 렌더링 하려면 setState를 사용해야 한다.

✔️ setState는 비동기적으로 동작하기 때문에 state가 직접 수정되어 여러번 상태를 업데이트 하는 경우, 이전 업데이트 내용이 다음 업데이트 내용에 덮어 쓰여질 수가 있어 예상치 못한 곳에서 버그가 발생 할 수 있습니다.

❗setState가 비동기적으로 처리되는 이유

state는 값이 변경되면 리렌더링이 발생한다. 그런데 변경되는 state가 많을 경우 리렌더링이 계속 일어날테고 속도도 저하될것이다.

따라서 React는 성능을 위해서 setState() 호출을 변경된 값들을 모아 단일 업데이트로 한꺼번에 진행하여 렌더링을 줄이고자 배치(Batch) 기능을 사용해 비동기로 작동한다고 볼 수 있다. 배치 업데이트는 16ms 주기이다. 비동기적으로 업데이트 될 수 있기 때문에 다음 state를 사용할 때 해당 값에 의존해서는 안 된다.

❗state 직접 수정시 render 함수가 실행되지 않는 이유

리액트가 웹 상에서 렌더링 되기 위해선 render() 메서드가 실행되어야 한다.
리액트의 컴포넌트는 생성된 후 Mount 상태에서 한 번 render() 메서드를 실행하고, 후에는 Update 상태에 진입해 shouldComponentUpdate의 값이 true일 때만 render() 메서드를 실행한다.
따라서, 우리가 변경한 state가 화면에 보이려면 Update 상태로 진입해야 한다는 것이다.

Update 상태에 진입하게 되는 상황

  • state or props의 변경
  • 부모 컴포넌트가 렌더링 됐을 때
  • forceUpdate 사용했을 때

💡state로 변경했을 때는 update 상태로 진입하지 않는다.

why

state 저장 방식이 '객체'이기 때문인데,
값이 변경 되었다는 걸 판단하기 위해서 리액트는 객체로 저장된 state를 비교 연산 하는데,
이 때 객체이기 때문에 비교하는 판단 근거가 객체의 메모리주소임으로 직접 state 값을 수정 할 경우 변경이 안 된 것으로 판단하고 Update 상태로 진입하지 않는 것이다
때문에 직접 변경하지 않고 새로운 객체를 만들어서 할당하는 것으로 변경해야 하고 그것을 위해 setState(),useState()를 사용하는 것이다.

참조 👇

0개의 댓글