ReactJS 렌더링 순서 이해하기

ReactJS에서 부모 및 자식 컴포넌트의 렌더링 순서 이해하기 ReactJS 초보자로서, 부모 컴포넌트와 자식 컴포넌트의 렌더링 순서에 대해 궁금해 할 수 있습니다. 이 블로그 글에서는 ReactJS에서 부모와 자식 컴포넌트의 렌더링 개념을 탐구하고, 자식 컴포넌트가 왜 부모 …

title_thumbnail(ReactJS 렌더링 순서 이해하기)

ReactJS에서 부모 및 자식 컴포넌트의 렌더링 순서 이해하기

ReactJS 초보자로서, 부모 컴포넌트와 자식 컴포넌트의 렌더링 순서에 대해 궁금해 할 수 있습니다. 이 블로그 글에서는 ReactJS에서 부모와 자식 컴포넌트의 렌더링 개념을 탐구하고, 자식 컴포넌트가 왜 부모 컴포넌트보다 먼저 렌더링되는지, 자식 컴포넌트의 렌더링이 실패하는 경우에는 어떻게 되는지 살펴보겠습니다.

먼저 자식 컴포넌트가 렌더링되는 이유

ReactJS에서 부모 컴포넌트가 렌더링될 때, 부모 컴포넌트는 자식 컴포넌트의 렌더 함수의 결과를 자신의 렌더 함수에서 사용해야 합니다. 이것이 자식 컴포넌트가 먼저 렌더링되는 이유입니다. 자식 컴포넌트를 먼저 렌더링함으로써, React는 부모 컴포넌트가 자식 컴포넌트에서 제공하는 필요한 데이터와 속성에 접근할 수 있도록 보장합니다.

또한, 자식 컴포넌트가 부모 컴포넌트의 children 속성으로 전달되는 경우에도 자식 컴포넌트는 부모 컴포넌트보다 먼저 렌더링됩니다. 이는 부모 컴포넌트가 추가 처리를 위해 자식 컴포넌트를 children 속성으로 받아야 하기 때문입니다.

더 잘 이해하기 위해 몇 가지 예제를 살펴보겠습니다:

class Parent extends React.Component {
  componentDidCatch() {}
  
  render() {
    return (
      <div>
        <Child />
      </div>
    );
  }
}

const Grandparent = () => <Parent />;

이 예제에서 Child 컴포넌트는 Parent 컴포넌트의 렌더 메소드 내에서 중첩된 요소입니다. 따라서 자식 컴포넌트가 먼저 렌더링되고 마운트됩니다. 자식 컴포넌트의 렌더링 중에 오류가 발생하면, 부모 컴포넌트의 componentDidCatch 라이프사이클 메소드에서 해당 오류를 catch하고 처리할 수 있습니다.

class Parent extends React.Component {
  componentDidCatch() {}

  render() {
    return <div />;
  }
}

const Grandparent = () => <Parent><Child /></Parent>;

이 예제에서 Child 컴포넌트는 Parent 컴포넌트의 children 속성으로 전달됩니다. 이 경우에는 자식 컴포넌트가 먼저 렌더링되지만 실제로 마운트되지 않습니다. 부모 컴포넌트가 자식 컴포넌트를 사용하지 않기 때문입니다. 결과적으로, 자식 컴포넌트는 실제로 Grandparent 컴포넌트에서 렌더링되므로, 부모 컴포넌트의 componentDidCatch 라이프사이클 메소드는 자식 컴포넌트에서 발생하는 오류를 catch하지 못할 것입니다.

자식 렌더링 실패 처리

React 버전 16 이전에는 개발자들은 자식 컴포넌트에서 오류를 처리하기 위해 unstable_handleError 라이프사이클 훅을 사용할 수 있었습니다. 그러나 React 16부터는 componentDidCatch 라이프사이클 메소드가 도입되어 자식 렌더링 실패 처리에 더 안정적이고 권장되는 접근 방식으로 사용됩니다.

다음은 componentDidCatch 메소드를 사용하여 에러 바운더리를 구현하는 예제입니다:

class ErrorBoundary extends React.Component {
  constructor(props) {
    super(props);
    this.state = { hasError: false };
  }

  componentDidCatch(error, info) {
    this.setState({ hasError: true });
    // 에러를 에러 보고 서비스에 기록하는 등 추가 작업도 수행할 수 있습니다.
    logErrorToMyService(error, info);
  }

  render() {
    if (this.state.hasError) {
      return <h1>에러가 발생했습니다.</h1>;
    }
    
    return this.props.children;
  }
}

위의 예제에서는 ErrorBoundary 컴포넌트를 정의하여 컴포넌트의 상태에 에러 상태를 설정합니다. componentDidCatch 메소드는 자식 컴포넌트의 렌더링 중에 오류가 발생하면 트리거됩니다. 이 메소드는 컴포넌트의 상태를 업데이트하여 오류가 발생했음을 나타냅니다. 또한 이 메소드를 사용하여 에러를 에러 보고 서비스에 기록하는 등의 작업을 수행할 수 있습니다.

에러 바운더리를 사용하려면, 에러를 처리하려는 컴포넌트를 ErrorBoundary 컴포넌트로 래핑하면 됩니다:

<ErrorBoundary>
  <MyWidget />
</ErrorBoundary>

MyWidget 컴포넌트에서 오류가 발생하는 경우, ErrorBoundary에 의해 catch되어 대체 UI가 렌더링됩니다.

결론

ReactJS에서 자식 컴포넌트는 부모 컴포넌트보다 먼저 렌더링되어 부모 컴포넌트가 자식에서 제공하는 필요한 데이터와 속성에 액세스할 수 있도록 보장합니다. React 16에서는 componentDidCatch 라이프사이클 메소드가 자식 렌더링 실패 처리에 권장되는 접근 방식으로 도입되었습니다. 에러 바운더리를 구현함으로써 자식 컴포넌트에서 발생하는 오류를 우아하게 처리하고 필요한 경우 대체 UI를 제공할 수 있습니다.

ReactJS에서 부모와 자식 컴포넌트의 렌더링 순서를 이해하고 렌더링 실패를 처리하는 방법은 견고하고 오류 내성 있는 애플리케이션을 개발하는 데 중요합니다. 따라서 ReactJS를 계속 탐색하고 사용하면서 이러한 개념을 기억해 두세요!

참고 자료 : 

reactjs

Leave a Comment