솔미는 성장중
[React 면접 대비] 가상돔 & react 공식문서(state) 본문
State의 깊은 중첩을 지양해야 하는 이유는 무엇일까요?
첫 번째로, 중첩된 객체의 state를 변경하기 어렵기 때문입니다. 중첩된 부분만 업데이트하기 위해선 깊은 복사를 수행해야 하고, 이는 복잡성을 증가시켜 코드의 가독성을 떨어뜨립니다. 두 번째로, 깊은 중첩된 state는 재사용이 어렵기에 다른 컴포넌트에서 필요한 부분만 추출하기 어렵습니다. 마지막으로 깊은 중첩된 State를 가진 컴포넌트는 State가 업데이트될 때마다 전체 컴포넌트가 리렌더링될 가능성이 높아집니다. 이는 성능 저하로 이어질 수 있으며, 불필요한 리렌더링을 발생시킬 수 있습니다. 따라서 가독성, 유지보수성, 성능 측면에서 state의 중첩을 최소화하는 것이 좋습니다.
브라우저의 렌더링 과정에 대해 간략히 설명해주세요. 가상 돔을 사용하면, 일반적인 렌더링 과정에서의 어떤 문제점을 개선할 수 있을까요?
1. DOM tree 생성
개발자가 작성한 HTML을 브라우저가 전달받으면, 브라우저의 렌더엔진이 이를 파싱
DOM node로 이루어진 트리 생성
2. Render tree 생성
CSS파일과 각 엘리먼트의 inline 스타일을 파싱하고, 스타일 정보를 추가하여 렌더트리 생성
3. Layout
각 노드들은 스크린의 좌표가 주어지고 정확히 어디에 배치될지 정해짐
4. Painting
화면에 나타날 내용을 그림
가상돔을 사용하면 전체 페이지를 다시 그리지 않고 변경 사항이 있는 부분에 대해서만 업데이트를 할 수 있습니다. 불필요한 렌더링 단계를 피할 수 있어서 비용이 줄어 성능이 향상됩니다. 또한 가상 DOM은 다양한 브라우저와 플랫폼에서 일관된 방식으로 작동하므로 크로스 플랫폼 호환성을 향상시켜줍니다.
useContext의 장점과 사용 시 주의사항을 말하세요
useContext를 사용하면 상태를 전역으로 관리할 수 있어서 어떤 컴포넌트에서든 동일한 데이터나 상태에 접근할 수 있습니다. 그래서 여러 컴포넌트 간에 데이터를 전달할 때 중간 부모 컴포넌트를 거치지 않고도 자식 컴포넌트에서 데이터에 접근할 수 있기 때문에 프로퍼티 전달이 간소화됩니다. 상태 관리 로직을 컴포넌트에서 분리하고, 그 상태를 필요한 다른 컴포넌트에서 재사용할 수 있는 것 또한 장점입니다.
useContext를 사용할 때 주의해야 할 점은 Provider에서 제공한 value가 달라진다면 useContext를 사용하고 있는 모든 컴포넌트가 리렌더링 된다는 점입니다. 따라서 useContext를 사용할 때 value 부분을 메모제이션 하는데에 신경을 써줘야 합니다
https://cocoon1787.tistory.com/801
useContext를 사용할 때 createContext 함수를 실행한 결과를 그대로 파라미터로 넘겨줘야 합니다.
가상 돔의 동작 원리를 diffing 알고리즘을 덧붙여 설명하세요
초기 렌더링 시에 초기 가상 DOM 트리가 생성됩니다. 상태가 변경되거나 이벤트가 발생하면 새로운 가상 DOM트리가 생성되는데 diffing 알고리즘을 통해 두 개의 가상 DOM트리가 비교됩니다. 어떤 부분이 업데이트가 필요한지 판단이 끝나면, 두 가상 DOM 트리 간의 차이를 파악하고, 최소한의 업데이트 작업을 수행합니다. 즉, 가상돔의 장점인 효율적인 업데이트의 핵심이 diffing 알고리즘입니다.
부모 컴포넌트에서 받아오는 prop이 계속해서 여러 하위 컴포넌트로 전달된다면 어떤 문제가 발생할 수 있나요?
많은 중간 컴포넌트를 거쳐 prop이 전달된다면 컴포넌트 계층 구조가 복잡해져서 코드의 가독성이 떨어지고, 유지보수가 어려워지는 문제가 있습니다. 또한 prop이 많은 중간 컴포넌트를 거치면서 불필요한 업데이트가 발생할 수 있습니다. 부모 컴포넌트에서 전달된 prop이 변경되면, 중간 컴포넌트에서도 리렌더링이 발생하기 때문에 성능 저하가 발생할 수 있습니다. 많은 컴포넌트가 같은 prop을 전달받으면 컴포넌트 간 의존성이 증가해 컴포넌트 재사용을 어렵게 만들기도 합니다.
이러한 문제를 해결하기 위해서 상태 관리 라이브러리를 활용해 중간 컴포넌트를 거치지 않고도 데이터를 공유할 수 있도록 설계하는 것이 좋습니다.
가상돔은 브라우저 렌더링 과정 중 Reflow, Repaint 두 과정을 줄여 성능상의 이점을 가져갑니다. 그럼 가상돔을 사용하지 않는다면 어떻게 저 두 과정을 최대한 효율적으로 줄일 수 있을까요?
DOM을 변경했을 때 또는 CSS 속성을 변경하면 reflow, repaint가 발생합니다.
즉, DOM의 변화와 CSS 속성 변화를 최소화하면 두 과정을 효율적으로 줄일 수 있습니다.
CSS 효율화, 레이아웃 변경 최소화, 렌더링 트리 최적화 등 다양한 방법이 있습니다.
구체적인 예시로는 display:none, transform opacity와 같이 reflow, repaint를 발생시키지 않는 속성을 사용하기, 다른 엘리먼트 레이아웃에 영향을 주지 않는 fixed와 absolute 속성 사용하기, DOM사용 최소화하기 등이 있습니다.
reflow가 일어나면 repaint 과정까지 일어나게 되므로 reflow가 일어나지 않게 만들면 더욱 효과적입니다.
https://webclub.tistory.com/346
prop을 state에 미러링하면 안되는 이유는 무엇인가요?
나중에 부모 컴포넌트에서 prop 값을 변경하더라도 state를 즉시 업데이트 하지 않는다면 props와 state간에 데이터 불일치 문제가 생길 수 있습니다. 이는 state가 첫 번째 렌더링 중에만 초기화되기 때문입니다. 그리고 props를 state로 미러링하면 두 가지 데이터 복사본이 메모리에 저장되기 되는데 이는 메모리 사용량을 늘리고 불필요한 자원 낭비를 초래할 수 있습니다.
특정 prop에 대한 모든 업데이트를 무시하려는 경우에는 큰 문제가 없을 수 있지만, 주의해서 사용해야합니다.
https://react-ko.dev/learn/choosing-the-state-structure#don-t-mirror-props-in-state
Props는 불변(Immutable)해야 합니다: React에서 Props는 부모 컴포넌트로부터 전달되고 자식 컴포넌트에서 변경해서는 안 되는 데이터입니다. Props는 부모 컴포넌트의 상태를 반영하고 있는데, 이를 그대로 State에 복사하면 컴포넌트 간의 데이터 일관성을 해치게 됩니다. 만약 State와 Props가 같은 값을 가지고 있으면, 컴포넌트가 예상치 못한 동작을 할 수 있습니다.
Props는 외부에서 제어되어야 합니다: Props는 부모 컴포넌트에서 변경되어야 하는 데이터이므로, State와 별개로 관리해야 합니다. State는 컴포넌트 내부에서 사용하고 업데이트하는 데 사용되며, Props는 외부에서 제어되는 데이터로서의 역할을 해야 합니다.
Props와 State의 업데이트 주기가 다릅니다: Props는 부모 컴포넌트가 업데이트될 때마다 새로 전달될 수 있으며, 이 때문에 State와 Props가 항상 동기화되지 않을 수 있습니다. 따라서 Props를 그대로 State에 복사하면 데이터의 불일치가 발생할 수 있습니다.
대신, State와 Props를 필요한 경우에 맞게 사용하고, 필요한 경우 State를 Props에 의존하도록 업데이트하는 것이 좋습니다. 만약 Props를 기반으로 State를 초기화하려는 경우, 컴포넌트가 처음 렌더링될 때 useState를 사용하여 Props 값을 초기 State 값으로 설정하는 것이 일반적인 패턴입니다. 그 후에는 State를 변경하거나 업데이트할 때 Props와 동기화하도록 로직을 작성해야 합니다.
React의 diff algorithmn은 어떤 식으로 동작해서 최적화에 도움을 주는 것인지 설명해주세요.
diffing 알고리즘은 2가지 기준을 가지고 있습니다.
- 서로 다른 type을 가지는 React Element는, 서로 다른 트리를 생성 할 것이다.
- 개발자는 'key'프로퍼티를 통해 리액트에게 해당 요소가 바뀌었는지 안바뀌었는지 힌트를 줄 수 있다.
- 루트 엘리먼트가 달라지면 그 트리를 완전히 버리고 새롭게 구축합니다.
- 속성이 바뀌는 경우엔 동일한 컴포넌트 인스턴스에 대해 속성만 업데이트 시켜주고, unmount는 일어나지 않으며 상태는 유지됩니다.
- 자식 컴포넌트가 바꾸는 경우엔 key를 비교해서 동일한 key 프로퍼티에 대해 리액트가 해당 프로퍼티가 이전 가상 DOM과 동일하다면, unmount 시키지 않습니다.
이 방법들을 통해 전체를 리렌더링하는 것이 아니라 변경된 부분에 대해서만 렌더링을 시켜줘서 react가 효율적으로 작동할 수 있게 해줍니다.
제어 컴포넌트와 비제어 컴포넌트의 차이점은 무엇이고, 각각 어떤 상황에서 사용하면 좋을까요?
제어 컴포넌트는 폼 요소의 상태를 React의 상태(State)로 관리하는 방식입니다. React가 상태를 관리하기 때문에 React의 일관성 있는 데이터 흐름을 유지할 수 있습니다. 상태 관리와 유효성 검사가 중요한 폼 요소나 다른 입력 요소에 주로 사용됩니다.
비제어 컴포넌트는 React 상태(State)에 의존하지 않고 DOM 요소의 참조를 직접 사용하는 방식입니다. 기존 코드와의 통합이나 외부 라이브러리와 함께 사용하거나, React 상태 관리의 복잡성을 피하고자 할 때 유용합니다. 일반적으로 React의 방식으로 상태를 관리하지 않고 직접 DOM을 조작해야 할 때 사용됩니다.
가상돔의 재조정과정에서 key의 역할과 index 사용을 지양해야하는 이유는 무엇인가요?
React는 key를 통해 기존 트리와 이후 트리의 자식들이 일치하는지 확인합니다
인덱스를 key로 사용 중 배열이 재배열되면 컴포넌트의 state와 관련된 문제가 발생할 수 있습니다. 컴포넌트 인스턴스는 key를 기반으로 갱신되고 재사용되기 때문에 인덱스를 key로 사용하면, 항목의 순서가 바뀌었을 때 key 또한 바뀔 것입니다. 그 결과로, 컴포넌트의 state가 엉망이 되거나 의도하지 않은 방식으로 바뀔 수 있으므로 index 사용을 지양해야 합니다.
'면접 대비' 카테고리의 다른 글
Recoil을 사용해보자 (0) | 2023.12.04 |
---|---|
[React 면접대비] (0) | 2023.09.09 |
[면접 대비] (0) | 2023.09.05 |
[TS 면접 대비] (0) | 2023.09.02 |