React 운영의 구조와 특징

eeensu·2023년 8월 2일
0

React 기본

목록 보기
6/22
post-thumbnail

React가 웹을 운영하는 법

React는 root element 내에서 모든 컴포넌트를 구성하고, 조합하며 유저에게 화면을 렌더링해준다. 또한 Virtual DOM을 사용하여 UI 업데이트를 효율적으로 처리하는데, 이 과정에서 특정한 알고리즘이 중요한 역할을 한다. 이러한 작동 방법은 어떻게 운영되는 것일까?

react는 선언적 API를 제공하기 때문에 갱신이 될 때마다 매번 무엇이 바뀌었는지를 걱정할 필요가 없다. 이는 애플리케이션 작성을 무척 쉽게 만들어주지만, react 내부에서 어떤 일이 일어나고 있는지는 명확히 눈에 보이지 않는다.

엘리먼트 (Element)는 react의 가장 작은 단위이며 불변객체이다. element를 생성한 이후에는 해당 element의 자식이나 속성을 변경할 수 없다. 상태의 변화가 일어남으로써, 리렌더가 일어날 때, 컴포넌트의 내용은 변경된다. 이때, 개발자는 element가 값이 "변경" 되는 것처럼 보인다고 생각할 수 있다. 하지만 이는 변경이 아닌 "대체" 에 가깝다.

이러한 알고리즘을 비교 알고리즘 (Diffing Algorithm) 라고 불린다. 중요한 것은, 개발자는 모든 컴포넌트들을 ReactDOM.render로 전달할 뿐 변경 및 판단은 react가 알아서 하기 때문에 그냥 react는 이러한 알고리즘을 사용하는 구나 라고 이해만 하면 된다.


비교 알고리즘(Diffing Algorithm)

react는 이전과 현재의 Virtual DOM을 비교하여 변경된 부분을 찾아내고, 실제 DOM에 최소한의 변경만을 적용한다. 이러한 과정을 비교 알고리즘이라고 한다. 상태가 변경될 때마다 react는 새로운 가상 DOM을 생성하고, 이전과 현재의 가상 DOM 트리를 비교하여 변경된 부분을 식별한다. 그 후 변경된 부분에 대해 필요한 업데이트만을 실제 DOM에 적용하여 성능을 최적화한다. 이를 통해 react는 UI 업데이트를 효율적으로 처리하면서도 예측 가능한 동작을 제공한다.


단계

  1. Element의 생성 및 업데이트
    react element를 생성하고 업데이트할 때, element의 타입(태그, key, props 순서)을 비교한다. 같은 타입의 element는 동일한 컴포넌트 인스턴스로 간주된다.

  2. 자식 Element의 비교
    element가 자식을 가지고 있는 경우, 자식 element들 이때 각 자식 element의 타입과 속성(props)을 비교하며, 변경된 부분을 찾아낸다.

  3. DOM 업데이트
    비교 결과를 바탕으로 변경이 필요한 부분을 실제 DOM에 업데이트한다. 변경된 부분만을 업데이트하므로서 성능상 이점을 얻을 수 있다.



react의 비교 알고리즘은 "얕은 비교" 방식을 사용한다. 즉, 객체의 속성을 재귀적으로 비교하지 않고, 단순히 참조 비교 (메모리 주소 비교)를 수행한다. 이로 인해 성능이 향상되지만, 객체 내부의 속성이 변경되었을 경우에는 감지하지 못하는 한계도 존재한다. 이를 극복하기 위해 불변성을 유지하면서 상태를 관리하는 것이 도움이 된다.




합성 / 추출 / 상속

react에서 컴포넌트를 구성하고 재사용하기 위해 사용되는 중요한 세 가지이다.

  • 컴포넌트의 합성 (Component Composition)
    작은 부분들을 조합하여 더 복잡한 컴포넌트를 만드는 것을 의미한다. 더 작고 간단한 컴포넌트을 생성하고, 이들을 조합하여 보다 큰 컴포넌트를 만드는 방식이다. 예를 들어, 버튼, 헤더, 프로필 이미지 등과 같은 작은 컴포넌트를 만들고, 이를 페이지 컴포넌트에서 조합하여 전체 페이지를 구성할 수 있다. 일반적으로 react에는 최상위에 단일 App 컴포넌트를 가지고 있다.

  • 컴포넌트의 추출 (Component Extraction)
    중복 코드를 줄이고 가독성을 높이기 위해 컴포넌트의 일부 코드(element)를 분리하여 새로운 컴포넌트로 추출하는 것을 의미한다. 유사한 UI나 로직을 가진 부분을 함수나 클래스로 추출하여 재사용 가능한 컴포넌트로 만든다. 예를 들어, 여러 곳에서 사용되는 일정한 스타일을 가진 버튼을 추출하여 재사용 가능한 버튼 컴포넌트로 만들 수 있다. 컴포넌트를 추출하는 작업은 지루할 수 있지만, 재사용가능한 컴포넌트들을 만들어 놓는 것은 더 큰 앱에서 작업할 때 두각을 나타낸다.

  • 컴포넌트의 상속 (Component Inheritance)
    react에서 컴포넌트 상속은 일반적으로 클래스 컴포넌트에서 사용되며, 부모 컴포넌트의 기능을 자식 컴포넌트에서 확장하는 개념을 의미한다. 예를 들어, 부모 컴포넌트에서 공통된 상태나 메소드를 정의하고, 이를 상속받은 자식 컴포넌트에서 추가 기능을 구현하여 확장할 수 있다.



Functional Component vs Class Component

react에서 Functional Component와 Class Component는 두 가지 주요한 컴포넌트 유형이다. 이들은 컴포넌트를 정의하는 방식과 몇 가지 기능에서 차이가 있다.

  • 함수형 컴포넌트 (Fuctional Component)
    함수로 정의되며, 함수의 형태로 컴포넌트를 생성한다. react의 이전 오래된 버전에서는, hook 함수 및 생명주기와 관련된 기능이 함수형 컴포넌트에는 존재하지 않았다. 때문에 class 컴포넌트를 주력으로 사용했다.

  • 클래스 컴포넌트 (Class Component)
    class 키워드로 정의되며, React.Component 를 확장하여 컴포넌트를 생성한다.
    react에서 Hooks가 도입되기 전까지는 생명주기(lifecycle) 메서드를 사용하여 컴포넌트의 동작을 제어하였다.

이후 react 16.8 버전 이후에 Hooks가 도입되면서 함수형 컴포넌트 에서도 상태(state)와 생명주기와 관련된 기능을 사용할 수 있게 되었다. 함수형 컴포넌트는 class 컴포넌트보다 상태관리와 생명주기 메서드의 유지보수가 더 효율적이고, 코드 양이 더 짧기에 직관적이며 가독성이 좋다는 장점이 있었다. 때문에 이 시점부터 react 개발자들은 class 형식에서 함수형 형식으로 많이 넘어갔다. 때문에 현재 블로그에서도 functional 형식으로 컴포넌트를 작성하고 있다.

profile
안녕하세요! 26살 프론트엔드 개발자입니다! (2024/03 ~)

0개의 댓글