본문 바로가기
Study Note/React

React #라우트 코드 스플리팅 #비동기적으로 코드 불러오기

by 시뮝 2021. 3. 15.
728x90

청크(chunk) 생성

페이지에서 필요한 코드들만 불러오려면, 청크(chunk)를 생성해야 한다. SplitMe.js 파일을 AsyncSplitMe.js 파일에서 비동기적으로 불러오는 소스이다.

 

SplitMe.js

import React from 'react';

const SplitMe = () => {
    return (
        <h3>
            청크
        </h3>
    );
};

export default SplitMe;

 

AsyncSplitMe.js

import React, { Component } from 'react';

class AsyncSplitMe extends Component {
    state = {
        SplitMe: null
    }

    loadSplitMe = () => {
        // 비동기적으로 코드를 불러옵니다. 함수는 Promise를 결과로 반환합니다.
        // import()는 모듈의 전체 네임스페이스를 불러오므로, default를 직접 지정해야 합니다.
        import('./SplitMe').then(({ default: SplitMe }) => {
            this.setState({
                SplitMe
            });
        });
    }

    render() {
        const { SplitMe } = this.state;

        // SplitMe가 있으면 이를 렌더링하고, 없으면 버튼을 렌더링합니다.
        // 버튼을 누르면 SplitMe를 불러옵니다.
        return SplitMe ? <SplitMe/> : <button onClick={this.loadSplitMe}>SplitMe 로딩</button>
    }
}

export default AsyncSplitMe;

 

App.js

import React from 'react';
import AsyncSplitMe from 'components/AsyncSplitMe';

const App = () => {
  return (
    <div>
      <AsyncSplitMe/>
    </div>
  )
}

export default App;

라우트 코드 스플리팅

비동기적으로 불러올 코드가 많은 경우 청크를 생성할 때마다 반복 작성해야 한다. 이를 편하게 구현할 수 있도록 따로 함수화한 asyncComponent.js 파일을 생성한다.

 

src>lib>asyncComponent.js

import React from 'react';

/**
 * 이 함수는 컴포넌트를 import하는 함수를 호출하는 함수를 파라미터로 받습니다.
 * 사용 예시) asyncComponent(() => import('./Home'))
 */
export default function asyncComponent(getComponent) {
    return class AsyncComponent extends React.Component {
        static Component = null;
        state = { Component: AsyncComponent.Component };

        constructor(props) {
            super(props);
            if(AsyncComponent.Component) return;

            getComponent().then(({default: Component}) => {
                AsyncComponent.Component = Component;
                this.setState({Component});
            });
        }

        render() {
            const { Component } = this.state;
            if(Component) {
                return <Component {...this.props} />
            }
            return null;
        }
    }
}

 

이동할 페이지 인덱스 파일을 두고 라우트 코드 스플리팅용 인덱스 index.async.js 파일을 생성한다. index.js와 index.async.js 파일을 분리하는 이유는 청크를 생성하여 코드 스플리팅을 하면 코드 내용을 변경했을 때 자동으로 새로고침하지 않기 때문에 개발 서버에서 비동기 라우트를 비활성화하기 위해서이다.

 

src>pages>index.async.js

import asyncComponent from "lib/asyncComponent";

export const Home = asyncComponent(() => import('./Home'));
export const About = asyncComponent(() => import('./About'));
export const Post = asyncComponent(() => import('./Post'));
export const Posts = asyncComponent(() => import('./Posts'));
(...)

 

 

코드 스플리팅은 프로젝트 규모가 클수록 더욱 빛을 발한다. 소규모 프로젝트라면 생략해도 된다. 나중에 파일 크기가 커지면 코드 스플리팅을 구현해도 무방하다.

728x90

댓글