React | 컴포넌트 성능 최적화 03 (불변성의 중요성 / 안해도 되는 경우)

Kate Jung·2021년 11월 7일
0

React

목록 보기
14/28
post-thumbnail

🔶 불변성의 중요성

매우 중요: (리액트 컴포넌트에서) 상태 업데이트 시 → 불변성 지키는 것

🔹 예시 코드 (onToggle) & 설명

const onToggle = useCallback((id) => {
    setTodos((todos) =>
      todos.map((todo) =>
        todo.id === id ? { ...todo, checked: !todo.checked } : todo,
      ),
    );
  }, []);
  • [ 구현 ] 기존의 데이터를 수정할 때

    → 직접 수정 x

    → 새 배열 제작 → 새 객체 제작 → 필요 부분 교체

  • 업데이트 필요한 곳에서는 새 배열/객체 제작 하기 때문에

    → React.memo 사용 시 : props 변화 파악해서 리렌더링 성능 최적화 가능

🔹 불변성을 지킨다 란?

== 기존 값: 직접 수정x & 새로운 값 제작

🔹 불변성 코드 예시

  • 배열
    const array = [1,2,3,4,5];
    
    // 나쁜 예
    const nextArrayBad = array; // 똑같은 배열 가리킴 (배열 복사x)
    nextArrayBad[0]=100;
    console.log(array === nextArrayBad) // 완전 같은 배열 (true)
    
    // 좋은 예
    const nextArrayGood = [...array] // 모두 복사 (배열 내부 값)
    nextArrayGood[0]=100;
    console.log(array === nextArrayGood) // 다른 배열 (false)
  • 객체
    const object = {
      foo: 'bar',
      value: 1
    }
    
    // 나쁜 예
    const nextObjectBad = object; // 같은 객체 가리킴 (복사x)
    nextObjectBad.value = nextObjectBad.value +1;
    console.log(object === nextObjectBad); // true (같은 객체)
    
    // 좋은 예
    const nextObjectGood = {
      ...object, // 모두 복사 (기존 내용)
      value: object.value+1 // 새로운 값 덮어 씀
    }
    console.log(object===nextObjectGood) // false (다른 객체)

🔹 불변성 안 지켰을 때

  • 객체 내부 값 → 새로워져도 바뀐 것 감지 x

    → React.memo에서 최적화(서로 비교) 불가능

🔹 전개 연산자(...문법) 사용 → 객체/배열 내부 값 복사 시

  • 얕은 복사 (shallow copy) 하게 됨

    = 가장 바깥쪽에 있는 값만 복사

  • 내부 값이 객체 or 배열일 경우

    내부 값 따로 복사 해야 함.

  • 예시 코드

    const todos = [{id: 1,checked: true},{id:2,checked: true}];
    const nextTodos = [...todos];
    
    nextTodos[0].checked=false;
    console.log(todos[0]===nextTodos[0]); // true (같은 객체 가리킴)
    
    nextTodos[0]={
      ...nextTodos[0],
      checked:false
    }
    console.log(todos[0]===nextTodos[0]); // false (새로운 객체를 할당)

🔹 객체 안에 있는 객체

  • 불변성 지키면서 새 값 할당 해야 함.

  • 예시 코드

    const nextComplexObject = {
      ...complexObject,
      objectInside:{
        ...complexObject.objectInside,
        enabled: false
      }
    }
    
    console.log(complexObject === nextComplexObject) // false
    console.log(complexObject.objectInside === nextComplexObject.objectInside) // false
  • immer의 활용

    → 복잡한 상황일 경우

    → 편하게 작업 가능

🔶 성능 최적화 안 해도 되는 경우

  • 내부 데이터 < 100개

  • 업데이트 자주 발생 x

profile
복습 목적 블로그 입니다.

0개의 댓글