React

State 불변성

nminy 2023. 4. 15. 16:10

: 메모리에 있는 값을 변경할 수 없는 것!

 

원시 데이터(숫자, 문자, 불리언... ) : 불변성 있음

원시데이터는 수정을 했을 때 메모리에 저장된 값 자체는 바꿀 수 없고, 새로운 메모리 저장공간에 새로운 값을 저장한다.

 

원시데이터가 아닌 것들(배열, 객체, 함수... ) : 불변성 없음

원시데이터가 아닌 데이터는 수정했을 때 기존에 저장되어 있던 메모리 저장공간의 값 자체를 바꿔버린다.

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

: 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;

index.js에서 주석처리하면 아래처럼 콘솔에서 하나만 나옴

 

랜더링

: 컴포넌트가 현재 props와 state의 상태에 기초하여 UI를 어떻게 구성할지 컴포넌트에게 요청하는 작업

 

배열 또는 객체가 나온다면 스프레드 문법 or map or filter,

불변성을 지켜주는 여러가지 방법이용해서 원시데이터가 아닌 것을 처리한다 

import React, { useState } from "react";

function App() {
  const [dogs, setDogs] = useState({
    name: 'merry',
    age: 5,
  });

  return (
    <div>
      <div>{dogs.name}</div>
      <button 
       onClick={() => {
        dogs.name = 'cutemerry'
        const dogs2 = { ...dogs }
        setDogs(dogs2)
      }}>
        버튼
        </button>
    </div>
  );
}

export default App;