language/react

React 개념 정리 5일차 (불변성, 컴포넌트 및 렌더링)

Front 주니어 2024. 9. 26. 10:25

불변성이란?

불변성이란 메모리에 있는 값을 변경할 수 없는 것을 말한다. 자바스크립트의 데이터 형태중에 원시 데이터는 불변성이 있고, 원시 데이터가 아닌 객체, 배열, 함수 불변성이 없다.

 

💡  사실 불변성이 좀 헷갈린다

  1. 변경 가능한 상황(=불변성이 없는 경우): 종이컵에 색깔을 칠하고, 그 위에 다른 색을 또 칠해서 원래 색을 가릴 수 있어요. 이것은 원래 종이컵의 색을 변경하는 것
  2. 변경 불가한 상황(=불변성이 있는 경우): 색깔이 칠해진 종이컵은 그 색을 바꿀 수 없다. 새로운 색을 사용하고 싶다면, 새로운 종이컵을 가져와야 하고 그 종이컵에 새로운 색을 칠해야 합니다. 

변경 가능한 방법

let numbers = [1, 2, 3];
numbers.push(4); // 배열에 직접 요소를 추가
console.log(numbers); // [1, 2, 3, 4]

자주 사용하던 방식이지만 위에 같은 방법은 문제가 있다고 한다...왜냐하면 불변성을 깨뜨리기 때문이다. 불변성을 깨뜨린다는 것은 원래의 데이터 구조를 직접 변경한다는 의미이며 이런 경우 원본 배열 numbers에 직접적으로 새로운 요소 '4'를 추가하고 있다.

 

불변성을 깨뜨리는 것이 왜 문제일까?

  1. 예측 불가능한 코드 : 데이터 구조를 직접 변경하면, 프로그램의 다른 부분에서 해당 데이터 구조를 참조하고 있을 때 그 부분들도 예상치 못한 방식으로 변경될 수 있다. 따라서 알 수 없는 버그를 발생시킬 수 있고 프로그램의 동작을 예측하기 어렵다.
  2. 버그 추적의 어려움 : 원본 데이터가 여러 곳에서 변결될 수 있다면, 어떤 부분의 코드가 데이터를 변경했는지 추적하기 어려워진다. 이는 특히 큰 코드베이스나 여러 개발자가 협업하는 환경에서 문제가 될 수 있다.

불변성을 유지하는 방법( Immutable way )

let numbers = [1, 2, 3];
let newNumbers = [...numbers, 4]; // 새 배열을 생성하여 기존 배열을 변경하지 않음
console.log(numbers); // [1, 2, 3]
console.log(newNumbers); // [1, 2, 3, 4]

 

React에서 불변성이 가지는 의의?

리액트에서는 화면을 리렌더링 할지 말지 결정할 때 state의 변화를 확인한다. state 변했으면 리렌더링 하는 것이고, state 가 변하지 않았으면 리렌더링을 하지 않는다. 

state가 변했는지 변하지 않았는지 확인하는 방법이 state의 변화 전, 후의 메모리 주소를 비교한다. 리액트에서 원시 데이터가 아닌 데이터를 수정할 때 불변성을 지켜주지 않고, 직접 수정을 가하면 값은 바뀌지만 메모리 주소는 변함이 없게 된다. 그래서 개발자가 값은 바꿨지만 리액트는 state가 변했다고 인지하지 못하게 되며 리렌더링이 일어나지 않는다!

 

리액트 불변성 지키기 예시

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;