티스토리 뷰

props는 읽기 전용입니다. 함수 컴포넌트나 클래스 컴포넌트 모두 컴포넌트의 자체 props를 수정해서는 안 됩니다. (리액트 공식문서 중)

 

리액트에서는 왜 props를 변경하지 못하게 하는 걸까?

 

리액트에서 컴포넌트는 다음과 같은 총 네 가지의 경우에 업데이트된다.

 

  1. props가 바뀔 때
  2. state가 바뀔 때
  3. 부모 컴포넌트가 리렌더링 될 때
  4. this.forceUpdate로 강제로 렌더링을 트리거할 때 

 

 기본적으로 리액트에서는 setState만을 사용하여 state를 변경하게 한다. 이는 상태가 변경될 때 리액트에게 리렌더링을 하라는 명령을 요청하기 위함이다. 즉, setState는 리액트에게 상태가 변경되었으니 리렌더링을 하라는 트리거이다. 하지만 props를 단순하게 할당연산자로 변경하는 경우 setState를 사용하지 않았기 때문에 props가 바뀌었음에도 불구하고 리액트가 상태가 변경됐는지 알아채지 못해 리렌더링을 하지 않는다. 만약 부모 컴포넌트의 state를 자식 컴포넌트에서 변경하고 싶다면 state 끌어올리기를 사용하면 된다. state 끌어올리기는 부모 컴포넌트의 state를 변경하는 함수(setState)를 자식 컴포넌트에게 props로 넘겨 자식 컴포넌트에서 부모의 state를 변경하게 하는 것이다.

 

 

리액트에서는 위와 같은 이유로 props의 변경을 원천 차단하고 있다.

import React from "react";

export default class Test extends React.Component {
  render() {
    this.props.name = "Lee";
    // TypeError: Cannot assign to read only property 'name' of object '#<Object>'
    return (
      <div>
        <h1>name: {this.props.name}</h1>
        <h1>age: {this.props.age}</h1>
      </div>
    );
  }
}

자식 컴포넌트에서 props를 변경하려고 하면 프로그램이 에러를 뱉으며 죽어버린다.

import React from "react";

export default class Test extends React.Component {
  render() {
    console.log(Object.getOwnPropertyDescriptor(this.props, 'name'))
    // {value: "kim", writable: false, enumerable: true, configurable: false}
    return (
      <div>
        <h1>name: {this.props.name}</h1>
        <h1>age: {this.props.age}</h1>
      </div>
    );
  }
}

객체의 속성을 보면 writable이 false임을 알 수 있다. 즉, 할당 연산자로 변경 자체가 불가능하게 설정되어 있다.

'웹 개발 > React' 카테고리의 다른 글

React Router의 Hash Router와 Browser Router  (1) 2021.06.10
Redux / React Redux / Redux Thunk  (0) 2021.06.08
제어 컴포넌트와 비제어 컴포넌트  (1) 2021.04.26
JSX  (0) 2021.04.26
리액트 동작 원리  (0) 2021.04.26