[React] setState & useState를 사용하는 이유 / TIL # 53

velg·2021년 9월 30일
9

React

목록 보기
6/10

setState & useState 를 사용하는 이유를 알아보자

의문

이 둘은 state값을 변경 시킬 때 사용하는 함수들이다
근데 왜 this.state.값 = 변경 값와 같이 변경하는 것이 아닌 이 두 함수를 사용하여 변경할까?

이유

의문을 갖고 직접 시도한 결과 직접 state를 변경할 시 변경된 값이 웹에 표시(렌더)되지 않았다

왜 그럴까?

그것은 React의 라이프 사이클의 흐름과 state의 저장방식을 알면 그 이유를 알 수 있다

라이프 사이클의 흐름

리액트가 웹 상에 렌더링 되기 위해선 render() 메서드가 실행되어야한다
리액트의 컴포넌트는 생성된 후 Mount 상태에서 한 번 render() 메서드를 실행하고, 후에는 Update 상태에 진입해 shouldComponentUpdate의 값이 true일 때만 render() 메서드를 실행한다 ( 이걸 뛰어넘는 메서드가 아래 설명된 forceUpdate 이다)

따라서 우리가 변경한 state가 화면에 보이려면 첫째로 Update상태에 진입해야한다

Update 상태에 진입하는 상황

  • state 또는 props가 변경
  • 부모 컴포넌트가 렌더링
  • forceUpdate 사용시

그럼 state를 직접 변경하면 Update상태에 진입 할텐데 무엇이 문제인가요? 🤔
이 것에 대한 이유는 아래에서 설명할 state의 특성 때문이다

state의 저장 방식

본론부터 이야기 하자면 state의 저장방식이 '객체'이기 때문이다

일단 예제를 보자

// 예제

import React from 'react';
import TestProps from './TestProps';

class App extends React.Component {
  constructor() {
    super();
    this.state = {
      MESSAGE: '부모 컴포넌트',
      MESSAGE2: '자식 컴포넌트',
    };
  }
  messageChange = () => {
    console.log('===== 메세지 변경 ======');
    console.log(this.state.MESSAGE);

    this.state.MESSAGE = '직접 변경!!!!!';
  };
  changeProps = () => {
    this.setState({ MESSAGE2: '프롭스 업데이트' });
  };
  render() {
    const { MESSAGE } = this.state;
    const val = '1';
    console.log('====== 렌더 ======');
    return (
      <>
        <h1>{MESSAGE}</h1>
        <TestProps message={this.state.MESSAGE2} />

        <button onClick={this.messageChange}>메세지 변경</button>
        <button onClick={this.changeProps}>체인지 프롭스</button>
      </>
    );
  }
}
export default App;

메세지 변경 버튼 클릭시 '부모 컴포넌트' 메세지가 '직접 변경!!!!!'으로 변경되는 컴포넌트를 간단하게 구현하고 메세지 변경을 클릭하였을 경우 아래 화면이 출력된다

image

하지만 콘솔에서 state의 값을 출력하였을 경우 아래와 같이 this.state.MESSAGE의 값이 변경된 것을 확인할 수 있다 image2

그럼 왜 Update 상태에 진입하지 않나요? 🤔

값이 변경 되었다는걸 판단하기 위해 리액트는 객체로 저장된 state를 비교 연산한다

이 때 객체이기 때문에 비교하는 판단 근거가 객체의 메모리 주소임으로 직접 state 값을 수정 할 경우 변경이 안된 것으로 판단하고 Update 상태로 진입 하지 않는 것이다

때문에 직접 변경하지 않고 새로운 객체를 만들어서 할당 하는 것으로 변경해야 하는 것이며 그 것을 위해 setState(), useState() 를 사용하는 것이다

번외) render()가 실행되지 않았을 뿐이다
조금 전에 직접 변경했던 메시지는 변경된 값이 정상적으로 저장되었지만 render()가 실행되지 않아 화면상에 보이지 않을 뿐이다
따라서 Update 상태로 진입하기 위해 props를 변경하였을 경우 직접 변경하였던 메세지가 변경되서 출력되는 것을 확인 할 수 있다
image3

profile
초보 개발자

0개의 댓글