React Object.is shallowEqual React.memo
- REACT & NODE
- 2024. 8. 27.
리액트 props 의 형태에 관한 질문
리액트에서 props 형태는 props 에 a , b, c , d 라는 프로퍼티가 있을 때 가령 b 를 배열, c 를 객체, d 를 깊이가 2 나 3인 객체 라고 하면 d 와 같은 형태는 사용하지 않는게 좋나요?
아니면 2중 3중 깊이의 객체나 배열도 그냥 불변성으로 항상 새로운 걸 만들어 넣는다는 개념으로 사용해도 될까요? 왠만하면 1깊이의 객체까지 한정해서 사용하고 불가피하게 필요할 경우에만 2중 3중 깊이의 객체를 사용할까요?
서버에서 받은 리스트 데이터를 넘겨줄 경우 하위 컴포넌트로 리스트 아이템 컴포넌트가 있을 때 리스트 데이터가 항상 새로운 불변의 객체니깐 하위인 리스트 아이템은 항상 리렌더링 되겠죠? 루프를 돌면서 map 같이 그려주는 경우 key 를 붙이는 이유가 이것 때문인가요? 그래서 key 가 같으면 리렌더링을 하지 않도록.
참고내용.
props 가 변경되면 리렌더링이 되는데 props 가 변경되었다의 기준이 shallowEqual 즉, 얕은 비교 (props 자체를 Object.is 로 비교하고 그 다음 props 의 첫번째 깊이의 속성값들을 Object.is 비교) 를 하여 변경되었다면 리렌더링.
React.memo 로 감싸준 경우 이러한 shallowEqual 해서 변경된 것이 없다면 부모가 리렌더링 될 때 React.memo 로 감싸준 컴포넌트가 자식이라면 리렌더링이 되지 않는다.
React에서 props를 다룰 때, 불변성을 유지하면서 깊이가 있는 객체나 배열을 사용할지 고민하는 것은 매우 중요한 주제입니다. 아래에서 제시한 질문들에 대해 차례대로 답변드리겠습니다.
1. 깊이가 있는 객체나 배열을 사용하는 것이 바람직한가요?
깊이가 있는 객체나 배열을 props로 사용하는 것은 가능합니다. 다만, 불변성을 유지하는 것이 중요합니다.
- 불변성 유지: React는 props의 얕은 비교를 통해 리렌더링 여부를 결정합니다. 따라서 깊이가 있는 객체를 사용하는 경우, 객체 내부의 데이터가 변할 때마다 새로운 객체를 만들어서 props로 전달해야 합니다. 이는 기본적으로 불변성을 유지하는 방식입니다.
- 깊이가 있는 구조의 사용 여부: 가능한 경우, props의 구조를 단순하게 유지하는 것이 좋습니다. 1단계 깊이의 객체나 배열로 표현할 수 있다면 그렇게 하는 것이 유지보수와 성능 면에서 더 나을 수 있습니다. 그러나, 만약 비즈니스 로직상 2단계나 3단계 깊이의 객체가 필요하다면, 불변성을 유지하면서 사용해도 괜찮습니다.
2. 서버에서 받은 데이터를 하위 컴포넌트로 넘길 때
서버에서 받은 데이터를 하위 컴포넌트로 넘겨줄 때, 그 데이터가 새로운 객체로 생성되면, 하위 컴포넌트는 항상 리렌더링될 가능성이 높습니다. 예를 들어, 다음과 같은 상황이 발생할 수 있습니다:
- 리스트 데이터와 리렌더링: 서버에서 받은 리스트 데이터를 하위 컴포넌트로 전달할 때, 리스트가 불변 객체로 관리된다면, 리스트 내의 아이템들이 새로운 참조를 가지게 됩니다. 이 경우 하위의 리스트 아이템 컴포넌트들은 리렌더링됩니다.
- 리렌더링을 방지하는 key 사용: map을 이용해 리스트를 렌더링할 때, React는 각 리스트 아이템에 key를 사용하여 각 아이템을 식별합니다. key는 React가 리스트의 각 항목을 추적하여, 동일한 항목에 대해 리렌더링을 방지하는 데 중요한 역할을 합니다. key가 같으면 React는 해당 컴포넌트를 재사용하고, 그렇지 않으면 리렌더링이 발생합니다.
3. React.memo와 shallow comparison (얕은 비교)
React.memo는 기본적으로 props의 얕은 비교(shallow comparison)를 통해 리렌더링 여부를 결정합니다. 얕은 비교는 다음과 같은 방식으로 이루어집니다:
- 객체의 참조 비교: React.memo는 props 자체를 Object.is를 사용해 비교하고, 각 props의 첫 번째 깊이의 속성값들을 비교합니다. 객체 내부의 깊은 속성들은 비교하지 않습니다. 따라서, 깊이 있는 객체가 props로 전달되었을 때 그 객체의 참조가 변경되면 리렌더링이 발생합니다.
- React.memo의 유용성: React.memo는 부모 컴포넌트가 리렌더링되더라도, 자식 컴포넌트의 props가 변경되지 않았다면 해당 자식 컴포넌트의 리렌더링을 방지해줍니다. 이는 성능 최적화에 큰 도움이 됩니다.
결론
- 깊이가 있는 객체나 배열을 사용할 때: 불변성을 유지하면서 깊이가 있는 구조를 사용할 수 있지만, 가능하면 props를 단순하게 유지하는 것이 좋습니다. 불가피한 경우에는 깊이가 있는 구조를 사용하되, 불변성을 엄격히 지켜야 합니다.
- 리스트 데이터와 리렌더링: 서버에서 받은 데이터를 하위 컴포넌트로 전달할 때, 불변 객체를 유지하면서 리렌더링을 최소화하려면 React.memo와 key를 잘 활용해야 합니다.
- React.memo의 유용성: 얕은 비교를 통해 성능을 최적화할 수 있으며, 깊이가 있는 객체는 참조가 변경되지 않도록 관리하는 것이 중요합니다.
결과적으로, React에서 props의 구조는 간결하고 불변성을 유지하는 방식으로 관리하는 것이 성능 최적화와 코드의 유지보수성 측면에서 좋습니다.
'REACT & NODE' 카테고리의 다른 글
react-query, TanQuery 서버 상태를 선언적으로 관리 (1) | 2024.09.03 |
---|---|
react-query vs redux, thunk (0) | 2024.08.28 |
React Native 0.73.1 변경내용. 20231219 (0) | 2023.12.19 |
react native animation (0) | 2023.10.13 |
react-native-firebase/messaging for push notification (2) | 2023.10.08 |