다음 내용은 책 '리액트를 다루는 기술'을 바탕으로 작성된 글입니다.
리액트 컴포넌트에서 상태를 업데이트할 때 불변성을 지키는 것은 매우 중요하다.
기존의 값을 직접 수정하지 않으면서 새로운 값을 만들어 내는 것을 '불변성을 지킨다'고 한다.
다음은 예시이다.
const array = [1,2,3,4,5];
const nextArrayBad = array; // 배열을 복사하지 않고 똑같은 배열을 참조함
nextArrayBad[0]= 100;
console.log(array === nextArrayBad); // 결과는 true
conset nextArrayGood = [...array]; // 배열 내부의 값을 모두 복사 -> 불변성 지켜짐
nextArrayGood[0]=100;
console.log(array === nextArrayGood); // 결과는 false
const object = {
foo: 'bar',
value: 1,
}
const nextObjectBad = object; // 객체를 복사하지 않고 똑같은 객체 참조
nextObjectBad.value = nextObjectBad.value+1;
console.log(object === nextObjectBad); // 결과는 true
cons nextObjectGood = {
...object, // 기존에 있던 내용을 모두 복사해서 넣는다.-> 불변성 지켜짐
value: object.value+1 // 새로운 값으로 덮어쓴다.
};
console.log(object === nextObjectGood); // 결과는 false
불변성이 지켜지지 않으면 객체 내부의 값이 새로워져도 바뀐 것을 감지하지 못 한다.
따라서 React.memo에서 서로 비교하여 최적화하는 것이 불가능해진다.
업데이트가 필요한 곳에 아예 새로운 배열 혹은 객체를 만들어 넣어야 React.memo를 사용했을 때 props가 바뀌었는지 혹은 바뀌지 않았는지를 알아내서 리렌더링 성능을 최적화해 줄 수 있다.
추가로 전개 연산자(... 문법)를 사용하여 객체나 배열 내부의 값을 복사할 때는 얕은 복사를 하게 된다.
즉, 내부의 값이 완전히 새로 복사되는 것이 아니라 가장 바깥쪽에 있는 값만 복사된다.
따라서 내부의 값이 객체 혹은 배열이라면 내부의 값 또한 따로 복사해주어야 한다.
다음은 예시이다.
👉 배열 안 객체
const todos = [{id:1, checked:true}, {id:2, checked:false}];
const nextTodos = [...todos];
console.log( todos === nextTodos) // false
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(complexObjext === nextComplexObject); // false
console.log(complexObject.objectInside === nextComplexObject.objectInside); // false
배열 혹은 객체의 구조가 정말 복잡해지면 이렇게 불변성을 유지하면서 업데이트 하는 것도 까다로워지는데,
이 경우 immer라는 라이브러리의 도움을 받으면 편하게 작업할 수 있다고 한다.
'Front-End > React' 카테고리의 다른 글
[React] 중첩된 라우트 , Outlet (0) | 2022.03.01 |
---|---|
[React] URL 파라미터와 쿼리스트링 (0) | 2022.02.25 |
[React] 리액트 라우터 (0) | 2022.02.25 |
[React] 컴포넌트 성능 최적화 : 많은 데이터 렌더링 (0) | 2022.02.24 |
[React] useCallback 함수 (0) | 2022.02.24 |