React _ 불변성

연정·2021년 10월 31일
0

React

목록 보기
4/9
post-thumbnail

React를 공부하다보니, React에서는 불변성이 매우 중요한 개념이라 한다.
불변성이 무엇이고 왜 중요한지, 그리고 어떤 식으로 활용되는지를 정리해보려고 한다.

Immutability _ 불변성

불변성은 말그대로 변하지 않는 성질을 말한다. React를 공부하다보면 'React의 불변성'이라는 말을 생각보다 자주 들을 수 있는데, React에서 말하는 불변성은 기존의 데이터를 건드리지 않고 사본을 생성하여 해당 사본으로 데이터를 교체하는 것을 말한다.

예를 들어, 아래의 방식은 객체에 직접 접근하여 데이터를 변경하는 것이다.

[객체 변경을 통한 데이터 수정]

var player = {score: 1, name: 'Jeff'};
player.score = 2;

// 이제 player는 {score: 2, name: 'Jeff'}입니다.

반면 아래의 방식은 기존 객체에 변형을 주지 않고 데이터를 변경하는 방법이다.

[객체 변경 없는 데이터 수정]

var player = {score: 1, name: 'Jeff'};

var newPlayer = Object.assign({}, player, {score: 2});
// 이제 player는 변하지 않았지만 newPlayer는 {score: 2, name: 'Jeff'}입니다.

기존 객체를 그대로 유지한 채 새로운 데이터를 포함한 객체를 생성한 아래의 방식이 React의 불변성을 지킨 예시라고 볼 수 있다.

왜 불변성이 중요할까?

React에서 불변성이 중요한 이유는 몇 가지가 있다.

  • 복잡한 특징들을 단순화
    직접적인 데이터 변경을 하지 않으면, 이전 버전의 데이터를 유지하고 재사용할 수 있게 된다. 그 결과로 이전 상황으로 돌아가거나 액션을 취소하고 다시 실행하는 등의 복잡한 특징들을 구현하기 쉽게 만들 수 있다.

  • 변화 감지
    객체를 직접적으로 수정하지 않는다면, 객체에서 변화를 감지하는 것은 매우 쉬워진다. 단순히 현재의 객체가 이전의 객체와 다르다면 변한 것이기 때문이다.

  • React에서 다시 랜더링하는 시기를 결정
    불변성의 가장 큰 장점은 React에서 순수 컴포넌트를 만드는 데 도움을 준다는 것이다. 변하지 않는 데이터는 변경이 이루어졌는지 쉽게 판단할 수 있으며 이를 바탕으로 컴포넌트가 다시 렌더링할지를 결정할 수 있다. (shouldComponentUpdate() 참고)

정리하면 React에서 불변성이 중요한 이유는, 비교대상을 유지하여 데이터에 변화가 있는지를 쉽게 판단할 수 있도록 함으로써 컴포넌트를 최적화하고 변화를 바탕으로 한 여러 상황을 쉽고 효율적으로 구현할 수 있도록 하기 때문이다.

컴포넌트 불변성 예시

아래의 코드를 살펴보자.
여기서 내가 구현하고 싶었던 내용은 댓글을 input 태그 내에 입력하고 엔터나 게시 버튼을 누를 경우 댓글이 화면에 추가되는 것이었다. 이를 위해 state값을 설정하고 addComment function을 통해 newComment의 value값인 string을 comments 배열에 추가하도록 하였다.

addComment function을 살펴보자.
comments 배열에 newComment를 추가하는 메소드로 concat() 이 사용되었다. 원래는 배열에서 값을 추가하는 메소드인 push()를 사용했었는데, 해당 메소드는 기존 데이터를 수정하는 메소드이기 때문에 제대로 작동하지 않았다. 반면 concat() 메소드는 인자로 주어진 배열이나 값들을 기존 배열에 합쳐서 새 배열을 반환하기 때문에 불변성을 유지할 수 있는 메소드이다.

class Feeds extends Component {
  constructor() {
    super();

    this.state = {
      comments: [],
      newComment: '',
    };
  }

  commentFormInput = e => {
    const { value } = e.target;
    this.setState({ newComment: value });
  };

  addComment = e => {
    const { comments, newComment } = this.state;
    this.setState({
      comments: comments.concat(newComment),
      newComment: '',
    });
  };
  
  render(){
  };
}

추가 information

Spread Operator (스프레드 연산자, 전개 구문)
스프레드 연산자는 string, array, object와 같이 반복 가능한 객체 (Iterable Object)에만 적용되며, 기존 대상을 얕게 복사하여 새로운 대상을 생성한다. 일반적으로 기존 데이터를 복사, 연결, 수정하는데 주로 쓰인다고 한다.


[배열에서의 스프레드 연산자]

var arr = [1, 2, 3];
var arr2 = [...arr]; // arr.slice() 와 유사
arr2.push(4);
// arr2 은 [1, 2, 3, 4] 이 됨
// arr 은 영향을 받지 않고 남아 있음

[객체에서의 스프레드 연산자]

var obj1 = { foo: 'bar', x: 42 };
var obj2 = { foo: 'baz', y: 13 };
var clonedObj = { ...obj1 };
// Object { foo: "bar", x: 42 }
profile
성장형 프론트엔드 개발자

0개의 댓글