본문 바로가기
React

[React] react-router-dom, loadable, history 를 이용한 페이지 이동 - 떽떽대는 개발공부

by 떽이 2021. 4. 2.

 

 

오늘은 react-typescript 에서 react-router-dom, loadable, history 를 이용하여 페이지 이동을 구현해보자.

먼저 필요한 모듈을 설치한다.

npm i -D @types/loadable__component @types/react-router-dom history
npm i @loadable/component react-router-dom

 

페이지 관리를 위하여 historyUtils.ts 파일을 작성한다.

src/utils/historyUtils.ts

import { createBrowserHistory } from 'history'

export enum HISTORY_ACTION_TYPE {
    POP = 'POP',
    PUSH = 'PUSH',
    REPLACE = 'REPLACE',
}
  
export const browserHistory = createBrowserHistory()

export function push(targetUrl: string) {
    browserHistory.push(targetUrl)
}
  
export function redirect(targetUrl: string) {
    browserHistory.replace(targetUrl)
}
  
export function reload() {
    window.location.reload()
}

export default browserHistory

 

실제 이동할 페이지의 url 을 관리하기 위해 CommonDomain.ts 를 작성한다.

export enum ROOT {
    MAIN = '/main',
    BOARD = '/board'
}

export const MAIN_ROUTES = {
    ROOT: `${ROOT.MAIN}`,
}

export const BOARD_ROUTES = {
    ROOT: `${ROOT.BOARD}`,
}

 

react-router-dom 의 Router로 모든 컴포넌트를 감싸준다.

src/index.tsx

import React from 'react'
import reactDOM from 'react-dom'
import { Router } from 'react-router-dom'

import { App } from '@/components/App'
import history from '@/utils/historyUtils'

window.onload = async () => {
    try{
        render()
    } catch (e) {
        console.error(e)
    }
}

function render(){
    reactDOM.render(
        <Router history={history}>
            <App />
        </Router>
    ,document.getElementById('app'))
} 

 

먼저 main 페이지로 접근 해서 메인페이지에서 board 페이지로 이동할 수 있도록 구현을 해보자.

src/components/App.tsx

import React from 'react'
import { Route, Switch } from 'react-router-dom'
import loadable from '@loadable/component'

import { ROOT } from '@/domains/CommonDomain'

export const App = () => {
    return (
      <Switch>
        <Route 
          path={ROOT.MAIN}
          component={loadable(() =>
          	import('./main'),
          )}
        />
        <Route 
          path={ROOT.BOARD}
          component={loadable(() =>
          	import('./board'),
          )}
        />
      </Switch>
    )
}

 

위의 코드에서 Switch 로 변경할 영역을 감싸주고 component 에서는 loadable() 을 사용하여 변경할 컴포넌트를 import 해주었다.

먼저 main 페이지를 처리할 것인데, 위의 코드에선 import('./main') 이라고 적었다.

main 디렉토리를 생성하고 index.tsx 파일을 작성한다.

src/components/main/index.tsx

import React from 'react'
import { Route, RouteComponentProps, Switch, withRouter } from 'react-router-dom'

import { MAIN_ROUTES } from '@/domains/CommonDomain'

import { Main } from './Main'

export default withRouter((routerProps: RouteComponentProps) => {
    return(
        <Switch location={routerProps.location}>
            <Route
                path={MAIN_ROUTES.ROOT} 
                component={Main}
            />
        </Switch>
    )
}) 

 

실제로 내용이 들어갈 Main.tsx 파일을 작성한다.

src/components/main/Main.tsx

import React from 'react'

import { push } from '@/utils/historyUtils'
import { BOARD_ROUTES } from '@/domains/CommonDomain'

export const Main = () => {
    const boardBtn = 'boardBtn'
    const onClick = () => {
        push(BOARD_ROUTES.ROOT)
    }

    return (
        <>
            <h2>Main</h2>
            <div>
                <label htmlFor={boardBtn}></label>
                <button 
                    id={boardBtn}
                    onClick={onClick}>
                    Board
                </button>
            </div>
        </>
    )
}

 

이렇게 하면 Main 페이지까지 구현이 완료 된다.

메인페이지에서 button 을 클릭하여 board 페이지로 이동할 수 있도록 onClick 함수에서 push 함수를 사용했다.

이 함수는 위에서 작성했던 historyUtils 를 모듈화 하여 가져온 것이다. 함수 실행 시 board 페이지로 이동된다.

board 페이지도 똑같이 작성한다.

src/components/board/index.tsx

import React from 'react'
import { Route, RouteComponentProps, Switch, withRouter } from 'react-router-dom'

import { BOARD_ROUTES } from '@/domains/CommonDomain'

import { Board } from './Board'

export default withRouter((routerProps: RouteComponentProps) => {
    return(
        <Switch location={routerProps.location}>
            <Route
                path={BOARD_ROUTES.ROOT} 
                component={Board}
            />
        </Switch>
    )
}) 

 

src/components/board/Board.tsx

import React from 'react'

export const Board = () => {
    return (
        <>
            Board
        </>
    )
}

 

결과는 아래와 같다.

 

 

댓글