< 목차 >
1. Immer
2. React에서 State 변형을 권장하지 않는 이유 5가지
3. State의 배열 업데이트하는 법
4. 금일 소감
오늘은 Study 때 내가 맡지 않았던 React 공식 문서 파트를 읽었다. 약간 밀렸어서 직전 스터디까지의 분량을 후루룩 읽었다. 새롭게 알게 된 부분과 궁금했던 부분에 대한 호기심이 풀려서 그 내용을 위주로 작성해 보려 한다!
1. Immer
: React에서 불변성(immutable state)을 관리하기 위한 라이브러리
Immer는 상태 업데이트 로직을 간단하고 읽기 쉬운 방식으로 작성할 수 있도록 해, 복잡한 객체의 불변 업데이트를 간단한 방법으로 처리할 수 있다. 기본적인 useState 훅과 유사하게 작동하며, 상태를 불변성을 유지하면서 업데이트할 수 있도록 도와준다.
사용법
- useImmer를 import 한다.
- 초기 상태를 설정하여 useImmer를 호출한다.
- 상태를 업데이트할 때는 제공되는 업데이트 함수를 사용하여 직접 변경한다.
예시 코드
import { useImmer } from "use-immer";
function App() {
const [state, updateState] = useImmer({ count: 0 });
function increment() {
updateState(draft => {
draft.count += 1;
});
}
return (
<div>
<p>{state.count}</p>
<button onClick={increment}>Increment</button>
</div>
);
}
이 코드에서 useImmer는 초기 상태 { count: 0 } 를 받고, increment 함수 내에서 상태를 직접 변경한다. 이 방법으로 상태 업데이트 시, 불변성을 유지할 수 있다.
2. React에서 State 변형을 권장하지 않는 이유 5가지
State를 변형하지 말란 건 알겠는데,
그렇다면 대체 '왜' React에서 State를 변형하지 말라고 하는지 궁금할 수 있다. React는 다음의 5가지 이유로 State를 변형하지 말 것을 주장했다.
- 디버깅: console.log를 사용하고 상태를 변경하지 않으면 과거 로그가 최근 상태 변경으로 인해 방해받지 않는다. 따라서 렌더링 간에 상태가 어떻게 변경되었는지 명확하게 확인할 수 있다.
- 최적화: 일반적인 React 최적화 전략은 이전 프로퍼티나 state가 다음 프로퍼티와 동일한 경우 작업을 건너뛰는 것에 의존한다. state를 변경하지 않는다면 변경이 있었는지 확인하는 것이 매우 빠르다. 만약 prevObj === obj라면, 내부에 변경된 것이 없다는 것을 확신할 수 있다.
- 새로운 기능: React가 개발 중인 새로운 React 기능은 State를 스냅샷처럼 취급하는 데 의존한다. 이전 버전의 State를 변경하는 경우 새로운 기능을 사용하지 못할 수 있다.
- 요구사항 변경: 실행 취소/다시 실행 구현, 변경 내역 표시, 사용자가 양식을 이전 값으로 재설정할 수 있도록 하는 등의 일부 애플리케이션 기능은 아무것도 변경되지 않은 상태일 때 더 쉽게 수행할 수 있다. 과거의 상태 복사본을 메모리에 보관했다가 필요할 때 재사용할 수 있기 때문이다. 변경 접근 방식으로 시작하면 나중에 이와 같은 기능을 추가하기 어려울 수 있다.
- 더 간단한 구현: React는 mutation(변형)에 의존하지 않기 때문에 객체에 특별한 작업을 할 필요가 없다. 많은 "반응형" 솔루션처럼 프로퍼티를 가로채거나, 항상 프록시로 래핑하거나, 초기화 시 다른 작업을 할 필요가 없다. 이것이 바로 React가 추가적인 성능이나 정확성의 함정 없이 아무리 큰 객체라도 상태에 넣을 수 있는 이유이기도 하다.
그니까.. React의 내부 설계가 State 변형에 따라
동작하게 돼있다는 거지?
State를 변형하면 최적화와 React의 새 기능을 사용하는 데 문제가 생길 수 있단 거고?
State가 원본 그대로면 메모리에 보관했다가 필요할 때 재사용하고?
[Reference]
- [React.dev] Updating Objects in State - https://react.dev/learn/updating-objects-in-state
3. State의 배열 업데이트하는 법
자바스크립트에서의 배열은 객체의 또 다른 종류일 뿐이다.
하지만, React에서의 모든 State는 '읽기 전용'으로 취급한다. 재할당, 변형시키는 메서드는 사용 불가하다.
또는 두 열의 메서드를 모두 사용할 수 있는 Immer를 사용할 수도 있다.
백그라운드에서 Immer는 항상 사용자가 초안에 적용한 변경 사항에 따라 다음 상태를 처음부터 다시 구성한다. 따라서 상태를 변경하지 않고도 이벤트 핸들러를 매우 간결하게 유지할 수 있다.
reverse
: 배열의 요소 순서를 반대로 뒤집음
이 메서드는 원본 배열 자체를 수정하며, 변경된 배열을 반환한다. 별도의 인자는 필요하지 않다.
예를 들어, [1, 2, 3] 배열에 reverse()를 적용하면 [3, 2, 1]로 변하고, 이 배열이 반환된다.
예시
let myArray = [1, 2, 3];
myArray.reverse();
console.log(myArray); // 출력: [3, 2, 1]
sort
: 배열의 요소를 정렬함. 문자열로 변환된 요소를 유니코드 코드 포인트의 순서에 따라 정렬함
이 메서드 역시 원본 배열을 변경하며, 변경된 배열을 반환한다. 사용자가 정렬 순서를 정의하고 싶다면, 비교 함수를 매개변수로 제공할 수 있다. 예를 들어, 숫자 배열을 정렬할 때는 숫자의 크기를 비교하는 함수를 사용해야 올바르게 정렬된다.
sort()는 기본적으로 문자열 비교를 사용한다.
숫자 배열을 정렬할 때는 비교 함수 (a, b) => a - b를 제공해 숫자 크기에 따라 정렬한다.
예시
let numbers = [3, 1, 4, 1, 5, 9];
numbers.sort((a, b) => a - b);
console.log(numbers); // 출력: [1, 1, 3, 4, 5, 9]
slice 와 splice 의 차이점
slice 와 splice 는 이름이 비슷하지만 매우 다르다.
- slice : 배열 또는 배열의 일부를 복사 가능
- splice : 배열을 변경 (항목을 삽입하거나 삭제하기 위해)
- React에서는 state의 객체나 배열을 변경하고 싶지 않기 때문에 slice (없음 p!)를 훨씬 더 자주 사용하게 될 것이다.
배열 내부의 객체 업데이트하기
객체는 실제로 배열 '내부'에 위치하지 않는다!
코드에서는 내부에 있는 것처럼 보일 수 있지만, 배열의 각 객체는 배열이 "가리키는" 별도의 값이다.
배열 내의 객체를 업데이트할 때, 배열은 객체에 대한 '참조를 저장'한다.
실제 객체는 배열 외부에 존재하고, 배열의 각 요소는 이러한 객체를 "가리키는" 참조로 구성된다. 따라서, 배열의 특정 요소(예: list[0])를 통해 객체의 속성을 변경할 때, 원본 객체가 직접 변경된다. 이는 React에서 상태 불변성을 유지하는 것이 중요한 이유 중 하나다.
객체를 수정할 때는 객체를 복사하고 수정한 후, 이를 새로운 상태로 설정해야 한다. 이렇게 하면 React에서 상태 변화를 감지하고 컴포넌트를 효과적으로 리렌더링할 수 있다.
[Reference]
- [React.dev] Updating Arrays in State - https://react.dev/learn/updating-arrays-in-state
4. 금일 소감
중간중간 드립 넣어가며 정리하면 더 행복하게 공부할 수 있다는 걸 깨달았다.
Immer라는 라이브러리를 몰랐는데 불변성을 위한 라이브러리고, useState 대신 사용하면 더욱 코드를 간결하고 깔끔하게 사용할 수 있다는 것을 새롭게 알게 되어 너무 유익하고 재밌었다.
기존에 알던 내용 계속 읽고 있으면 표정이 이렇게 된다
새로운 내용을 아는 건 늘 새롭고 짜릿하다..
아 그리고 복습 좀 열심히 해야겠다. 새로운 내용을 좋아하다 보니, 봤던 내용을 다시 안 보게 되는 불상사가,, 복습 파이팅...
'[Front-end] 개발자 공부' 카테고리의 다른 글
[개발 공부 75일차] Managing State | React 공식 문서 Study (0) | 2024.07.01 |
---|---|
[개발 공부 74일차] 댓글 미반영, 유저 유형 안 보이는 이슈 해결 (0) | 2024.06.24 |
[개발 공부 72일차] React 공식 문서 Study | Adding Interactivity (2) | 2024.06.16 |
[개발 공부 71일차] 비동기 DAY | React Query, Thunk, Promise (0) | 2024.06.12 |
[개발 공부 70일차] DOM과 React의 작동 원리, 가비지 컬렉터 (2) | 2024.06.10 |