개발의 모든것/React

리액트 동작원리 , State를 직접 수정하면 안되는이유

연재몬 2022. 3. 25. 00:33

리액트는 변경사항이 한가지의 방향으로만 흘러간다.

: 데이터(State)가 변경이 되면 → 리액트가  render() 함수를 호출해서 UI가 업데이트 된다.

코드 상으로 보면 클래스 컴포넌트이고, this.state에는 숫자를 담을 수 있는 count가 들어있는 오브젝트가 있다.

그리고 button이 클릭되면 onClick 콜백이 실행될 것이고, 거기에서 우리가 State를 업데이트 시켜 주면 된다 :)

 


State를 바로 수정하는 경우 💩

위와 같이 this.state.count++ 바로 this.state가 가리키고 있는 오브젝트의 count를 증가 시켜 주면 업데이트가 되지않는다.

리액트에서 제대로 상태를 업데이트 하기 위해서는 리액트에서 제공하는 setState 함수를 호출해야 한다 !!

 


리액트 제대로 업데이트 하기 🚀

상태가 변할때마다(State의 데이터가 업데이트 될떄마다) 우리가 원하는대로, 의도한대로 컴포넌트를 업데이트 하기 위해서는, 

리액트에서 제공하는 setState 함수를 호출해야한다. 

setState 함수를 이용해서

새로운 상태 오브젝트(업데이트 하고자 하는 상태 데이터)를 인자로 전달해 주는것을 볼 수 있듯, 

리액트가 업데이트가 되어야 한다고 알아 차리게 하기 위해서는 이렇게 setState 함수를 호출해 주어야한다.

 

그렇게 해야 리액트가,

아! 상태가 업데이트 되었군, 그럼 이제 UI를 업데이트 하기 위해서 render 함수를 호출해줘야지! 라고 알아 차리게 되는 것 

 

=>  setState 함수가 호출이 되면 이제 리액트는 현재 컴포넌트가 가지고 있는 상태와 (this.state), 

데이트 해야 하는 새로운 상태 (setState 함수의 인자로 전달된 새로운 오브젝트) 두가지를 비교해서 

업데이트가 필요한 경우 해당 컴포넌트의 render 함수를 호출

 


💡 setState는 비동기 API

webAPIs 중 하나인 setTimeout, setInterval과 같은 비동기 함수처럼, setState도 비동기 함수.

그말은 setState를 호출한다고 해서 무조건 바로 render 함수가 호출되는 것이 아니라,

리액트에 업데이트 요청을 하기만 하고 다시 뒤에 이어지는 코드가 실행이 되어진다. 

비동기로 동작하기 때문에 리액트가 동시 다발적으로 요청된

여러가지의 setState를 더 효율적으로 처리 할 수 있다.

 


정말 중요 🚨

그리고, state를 업데이트 할때 이전 state 값에서 무언가가 계산이 되어지는 경우라면 (예제 코드)

컴포넌트 내의 state 값에 의존해서 계산한 값을 setState(updated)로 설정하기 보다는, 

setState(prevState => newState) 이렇게 이전 state 값을 받아서 그걸로 업데이트 되는 state값을 만드는

arrow function을 전달할 수 있는 함수 호출을 하는게 좋다 

 

리액트에서 제공하는 setState는 함수**

  • setState(newState)  // 새로운 state 오브젝트를 인자로 바로 받는 함수
  • setState(prevState => { return newState; }) 

        // 이전 state를 받아서 그걸로 계산해서 새로운 state를 리턴하는 함수를 인자로 받는 함수


State를 수정하면 안되는 이유? 💩

setState는 비동기적으로 동작한다

 리액트의 setState 함수 호출은 비동기적으로 처리 됩니다.

그래서 State를 직접 수정하면서 여러번 상태를 업데이트 하는 경우

이전 업데이트 내용이 다음 업데이트 내용으로 덮어 쓰여질 수 있고,

비동기 특성으로 인해 예상치 못한 곳에서, 예상치 못한 순간에 🐛 버그가 발생 할 수 있는 위험이 있다.

 

절대절대 직접 수정하지말자