본문 바로가기
SPA/React

[React] Router를 타입스크립트와 같이 사용하는 방법

by J4J 2021. 8. 11.
300x250
반응형

안녕하세요. J4J입니다.

 

이번 포스팅은 Router를 타입 스크립트와 같이 사용하는 방법에 대해 적어보는 시간을 가져보려고 합니다.

 

 

 

우선 들어가기에 앞서 이전에 Router를 이용한 페이지 이동하는 방법에 대해 글을 올린적이 있습니다.

 

타입 스크립트를 사용한다고 하더라도 router를 사용하는 것에 있어서 크게 다를 것은 없지만 일부 기능들은 타입을 지정해줘야 사용할 수가 있습니다.

 

대표적으로 history, location, match가 있는데 이들을 제외한 나머지는 사용방법이 동일하기 때문에 이전 글을 참조하시길 바랍니다.

 

 

 

※ 추가 → 해당 글은 react router v6 업그레이드 이전에 작성된 글입니다. 현재 최신 버전을 설치할 경우 다른 점이 존재할 수 있으니 변경점에 대해 확인이 필요하신 분들은 [React] React Router v5와 v6 비교하기를 참고해주시길 바랍니다.

 

※ 추가 → react router v6 업그레이드된 사항에 맞게 새롭게 정의된 router 사용 방법이 필요하신 분들은 [React] react-router 사용하기를 참고해주시길 바랍니다.

 

 

반응형

 

 

Router 설정

 

[ 1. 패키지 설치 ]

 

$ npm install react-router react-router-dom 
$ npm install -D @types/react-router @types/react-router-dom

 

 

[ 2. index.tsx에 BrowserRouter 추가 ]

 

import * as React from 'react';
import ReactDom from 'react-dom';
import App from './App';
import { BrowserRouter } from 'react-router-dom';

ReactDom.render(
    <BrowserRouter>
        <App />
    </BrowserRouter>, 
    document.querySelector('#root'))
;

 

 

[ 3. App.tsx에 Route 설정 ]

 

App.tsx에서는 다음과 같이 Router설정을 해보겠습니다.

 

import * as React from 'react';
import { Route, Switch } from 'react-router';
import HelloReact from './helloReact';
import HelloTypeScript from './helloTypeScript';

const App = (): JSX.Element => {

    return (
        <Switch>
            <Route exact path='/helloReact' component={HelloReact}/>
            <Route exact path='/helloTypeScript' component={HelloTypeScript}/>
        </Switch>
    )
}

export default App;

 

 

 

맨 위에 링크 걸어둔 포스팅을 보셨다면 위의 설정이 어떻게 되어있는 것인지 이해가 되실 겁니다.

 

url에 도메인+/helloReact를 입력하게 되면 helloReact.tsx에 구현해둔 내용들이 화면에 보이게 되고 도메인+/helloTypeScript를 입력하게 되면 helloTypeScript.tsx에 구현해둔 내용들이 화면에 보이게 됩니다.

 

 

 

혹시나 궁금해하실 분이 계실 것 같아서 말씀드리는데 helloReact와 helloTypeScript파일은 App.tsx와 동일한 위치에 다음과 같이 만들어 놨습니다.

 

// helloReact.tsx

import * as React from 'react';

const HelloReact = (): JSX.Element => {
    
    return (
        <div>
            <h2>Hello React!</h2>
        </div>
    )
}

export default HelloReact;

 

// helloTypeScript.tsx

import * as React from 'react';

const HelloTypeScript = (): JSX.Element => {
    return (
        <div>
            <h2>Hello TypeScript!</h2>
        </div>
    )
}

export default HelloTypeScript;

 

 

 

 

History 사용 방법

 

설정을 모두 마쳤다면 history를 사용하는 방법에 대해 말씀드리겠습니다.

 

간단하게 App.tsx파일이 마운트될 때 history를 이용하여 helloReact화면이 나오도록 해보겠습니다.

 

 

 

우선 useHistory를 이용하는 방법입니다.

 

해당 방법은 다음과 같이 TypeScript를 사용하지 않을 때와 동일합니다.

 

import * as React from 'react';
import { Route, Switch, useHistory } from 'react-router';
import HelloReact from './helloReact';
import HelloTypeScript from './helloTypeScript';

const App = (): JSX.Element => {

    const history = useHistory();

    React.useEffect(() => {
        // 마운트 될 때 /helloReact로 페이지 이동
        history.push('/helloReact');
    }, [])

    return (
        <Switch>
            <Route exact path='/helloReact' component={HelloReact}/>
            <Route exact path='/helloTypeScript' component={HelloTypeScript}/>
        </Switch>
    )
}

export default App;

 

 

 

하지만 파라미터로 history를 받아와 사용할 때는 다른 점이 있습니다.

 

import * as React from 'react';
import { Route, RouteComponentProps, Switch, withRouter } from 'react-router';
import HelloReact from './helloReact';
import HelloTypeScript from './helloTypeScript';

const App: React.FC<RouteComponentProps> = ({ history }): JSX.Element => {

    React.useEffect(() => {
        // 마운트 될 때 /helloReact로 페이지 이동
        history.push('/helloReact');
    }, [])

    return (
        <Switch>
            <Route exact path='/helloReact' component={HelloReact}/>
            <Route exact path='/helloTypeScript' component={HelloTypeScript}/>
        </Switch>
    )
}

export default withRouter(App);

 

 

 

코드를 보신것 처럼 파라미터의 타입을 지정해주기 위해 RouteComponentProps를 제네릭으로 설정하고 또한 export를 이용해 모듈화를 해줄 때 withRouter를 붙여줘야 합니다.

 

타입 스크립트 설정을 어떻게 해줬냐에 따라 위의 설정을 안 해줘도 문제가 발생되지 않겠지만 타입 관련 에러가 발생될 때는 위와 같이 설정을 해주셔야 합니다.

 

추가적으로 제 경험상 withRouter같은 경우는 App.tsx에서만 해주고 나머지 파일들에서는 RouteComponentProps만 설정해주면 되는 것으로 알고 있습니다.

 

 

 

 

Location 사용 방법

 

결론부터 말씀드리면 location은 history와 동일합니다.

 

useLocation을 사용하면 TypeScript를 사용하지 않을 때와 사용방법이 동일합니다.

 

import * as React from 'react';
import { Route, Switch, useLocation } from 'react-router';
import HelloReact from './helloReact';
import HelloTypeScript from './helloTypeScript';

const App = (): JSX.Element => {
    const location = useLocation();

    React.useEffect(() => {
        // 마운트 될 때 location 정보 출력
        console.log(location);
    }, [])

    return (
        <Switch>
            <Route exact path='/helloReact' component={HelloReact}/>
            <Route exact path='/helloTypeScript' component={HelloTypeScript}/>
        </Switch>
    )
}

export default App;

 

 

 

하지만 파라미터로 받아 올 경우에는 타입 관련 에러가 발생될 때 다음과 같이 설정해주시면 됩니다.

 

import * as React from 'react';
import { Route, RouteComponentProps, Switch, withRouter } from 'react-router';
import HelloReact from './helloReact';
import HelloTypeScript from './helloTypeScript';

const App: React.FC<RouteComponentProps> = ({ location }): JSX.Element => {

    React.useEffect(() => {
        // 마운트 될 때 location 정보 출력
        console.log(location);
    }, [])

    return (
        <Switch>
            <Route exact path='/helloReact' component={HelloReact}/>
            <Route exact path='/helloTypeScript' component={HelloTypeScript}/>
        </Switch>
    )
}

export default withRouter(App);

 

 

 

 

Match 사용 방법

 

가장 먼저 App.tsx파일을 다음과 같이 수정해보겠습니다.

 

import * as React from 'react';
import { Route, RouteComponentProps, Switch, withRouter } from 'react-router';
import HelloReact from './helloReact';
import HelloTypeScript from './helloTypeScript';

const App: React.FC<RouteComponentProps> = ({ history }): JSX.Element => {

    React.useEffect(() => {
        // 마운트 될 때 /helloTypeScript로 페이지 이동
        history.push('/helloTypeScript/123');
    }, [])

    return (
        <Switch>
            <Route exact path='/helloReact' component={HelloReact}/>
            <Route exact path='/helloTypeScript/:number' component={HelloTypeScript}/>
        </Switch>
    )
}

export default withRouter(App);

 

 

 

페이지가 처음 마운트 되어서 helloTypeScript로 페이지 이동을 할 때 number라는 resource를 같이 넘겨주려고 합니다.

 

helloTypeScript에서 number값을 받아와 출력해보도록 하겠습니다.

 

 

 

우선 useRouteMatch를 이용하는 방법입니다.

 

import * as React from 'react';
import { useRouteMatch } from 'react-router';

interface ImatchParams {
    number: string;
}

const HelloTypeScript = (): JSX.Element => {

    const match = useRouteMatch<ImatchParams>();

    React.useEffect(() => {
        // 마운트 될 때 number값 출력
        console.log(`number값: ${match.params.number}`);
    }, [])

    return (
        <div>
            <h2>Hello TypeScript!</h2>
        </div>
    )
}

export default HelloTypeScript;

 

 

 

타입 스크립트를 사용하지 않을 때와 다른 점은 useRouteMatch에 resource에 대한 타입을 지정한 인터페이스를 제네릭으로 설정해줘야 합니다.

 

 

 

 

또 다른 방법으로는 history, location처럼 파라미터로 받아오는 방법이 있습니다.

 

import * as React from 'react';
import { RouteComponentProps } from 'react-router';

interface ImatchParams {
    number: string;
}

const HelloTypeScript: React.FC<RouteComponentProps<ImatchParams>> = ({ match }): JSX.Element => {

    React.useEffect(() => {
        // 마운트 될 때 number값 출력
        console.log(`number값: ${match.params.number}`);
    }, [])

    return (
        <div>
            <h2>Hello TypeScript!</h2>
        </div>
    )
}

export default HelloTypeScript;

 

 

 

match도 history, location과 마찬가지로 타입 스크립트 설정을 어떻게 했냐에 따라 위와 같이 타입 설정을 안해도 문제가 발생되지 않을 수도 있지만 타입 문제가 발생되면 위와 같이 설정을 해줘야 합니다.

 

그리고 만약 넘어오는 resource없이 match만 사용하고자 한다면 ImatchParams와 관련된 코드들은 모두 제거해주셔도 상관없습니다.

 

 

 

 

 

 

이상으로 Router를 타입 스크립트와 같이 사용하는 방법에 대해 간단하게 알아보는 시간이었습니다.

 

읽어주셔서 감사합니다.

 

 

 

728x90
반응형

댓글