본문 바로가기
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
</>
)
}

 

결과는 아래와 같다.

 

 

댓글