ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [ React ] 리액트에서 불변성을 지켜주는 것이 중요한 이유
    TIL 2024. 1. 25. 23:00
    728x90

     

    불변성이란?

    불변성이란 메모리에 있는 값을 변경할 수 없는 것을 말한다.

    원시 데이터 (Boolean, Number, String, null, undefined, Symbol)는 불변성이 있고,

    원시 데이터가 아닌 객체, 배열, 함수는 불변성이 없다.

     

    만약 let number = 1 이라고 선언한다면,

    메모리에는 1이라는 값이 저장된다.

    그리고 number 라는 변수는 메모리에 저장된 1을 참조한다.

     

    주소 5001 5002
    1 ...

     

    그런데 let secondNumber = 1 이라고 다른 변수를 선언한다면?

    이때도 자바스크립트는 이미 메모리에 생성된 1이라는 값을 참조한다.

     

    즉, 변수 number와 secondNumber는 변수의 이름은 달라도,

    같은 메모리의 값을 바라보고 있는 것이다.

    그래서 console 에 number === secondNumber 를 하면 True가 보이는 것이다.

     

     

    하지만 원시데이터가 아닌 객체, 배열, 함수는 이렇지 않다.

    let obj_1 = { name : 'kim' } 이라고 선언하면 메모리에 obj_1이 저장된다.

    그리고 이어서 let obj_2 = { name : 'kim' } 이라고 같은 값을 선언하면 어떻게 될까?

     

    주소 7001 (obj_1) 7002 (obj_2)
    { name : ' kim ' } { name : ' kim ' }

     

     let obj_2 = { name : 'kim' } 의 값은 obj_2 라는 메모리 공간에 새롭게 저장이 된다.

    그래서 obj_1 === obj_2 false 가 된다

     


     

    원시 데이터로 돌아와서 만약 기존에 1이던 number를 number = 2 라고 새롭게 값을 할당하면?

    원시데이터는 불변성을 가지고 있기에

    기존 메모리에 저장된 1은 사라지지 않고

    새로운 메모리 저장공간에 2가 생긴 뒤,

    선언된 number = 2 는 새롭게 저장 공간이 생긴 2를 바라본다.

     

    여기서 secondNumber 를 콘솔에 찍는다면 여전히 1이 나온다.

    number 와 secondNumber 은 서로 다른 메모리를 참조하기 때문이다.

     

    하지만 불변성이 없는 객체는 obj_1 의 name 을 ' park ' 으로 수정한다면

    기존 메모리 저장공간에 있던 { name : 'kim' } 은 { name : 'park' } 으로 바뀐다.


     

    리액트에서 원시 데이터가 아닌 데이터의 불변성을 지켜주는 중요성

     

    리액트는 화면을 렌더링 할지 말지 결정을 state 의 변화를 통해 결정한다.

    즉, state 가 변했으면 리렌더링, state 가 변하지 않았으면 리렌더링을 안한다.

     

    이 state 의 변화를 확인하는 방법이 state 변화 전, 후의 메모리 주소를 비교하는 것이다.

    그래서 리액트에서 원시데이터가 아닌 데이터를 수정할 때 불변성을 지켜주지 않고

    직접 수정을 하면 값은 바뀌어도 주소는 바뀌지 않기 때문에 리렌더링을 안한다.

     

    즉, 개발자는 값을 바꿨지만 리액트는 state 의 변화가 없다고 판단해 인지하지 못하는 것이다.

     


     

    리액트에서 불변성을 지키는 방법

     

    배열을 setState 할 때 불변성을 지켜주기 위해선

    직접 수정을 가하는 것이 아닌 전개 연산자(...) 를 사용해 기존의 값을 복사하고 수정해야한다.

     

    import React, { useState } from "react";
    
    function App() {
      const [dogs, setDogs] = useState(["말티즈"]);
    
      function onClickHandler() {
    		// spread operator(전개 연산자)를 이용해서 dogs를 복사합니다. 
    	  // 그리고 나서 항목을 추가합니다.
        setDogs([...dogs, "푸들"]);
      }
    
      console.log(dogs);
      return (
        <div>
          <button onClick={onClickHandler}>버튼</button>
        </div>
      );
    }
    
    export default App;
    728x90
Designed by Tistory.