본문 바로가기

React

[React] Route를 이용한 Component 전환

[해당 포스트는 개인적으로 공부를 하고 차후에 참고용으로 하고자 작성한 것입니다.
따라서 잘못된 부분이나 부족한 부분이 있을 수 있기에 참고하시기 바랍니다.]

이번엔 react-router-dom Module를 이용하여 Component를 전환하는 방식에 대해서 알아보자.

 

시작에 앞서 다음의 Module을 설치해주자.

  • react-router-dom
  • query-string

react-router-dom에서 실습할 함수는 3가지가 존재한다.

  • BrowserRouter
  • Route
  • Link

BrowserRouter

지정한 Component를 Main Router로 지정해준다.

해당 Component에서 다른 Component들을 전환시켜줄 수 있게 된다.

우선 Root.js를 생성해서 다음과 같이 입력한다.

 

import React, { Component } from 'react';
import { BrowserRouter } from 'react-router-dom';
import App from './App';

class Root extends Component {
  render() {
    return (
      <div>
        {/* 앞으로 App는 Router라는 것을 설정 */}
        <BrowserRouter>
          <App/>
        </BrowserRouter>
      </div>
    );
  }
}

export default Root;

 

BrowserRouter 태그 사이에 Main Route로 사용할 태그를 추가한다.

이제부터 Main Route는 App가 될 것이다.

App는 rcc를 통해서 Component로 생성해주자.

 

import React, { Component } from 'react';

class App extends Component {
    render() {
        return (
            <div>
                <h1>App is called!</h1>
            </div>
        );
    }
}

export default App;

 

Route

지정한 Component로 전환시켜준다.

사용하기 위해 react-router-dom 모듈을 가져와 Route를 import 시켜주자.

Route함수는 태그 형태로 호출하는데 처음으로 사용할 속성은 2가지가 존재한다.

  • path : 접근할 경로를 설정한다.
  • component : 전환할 Component를 설정한다.

Bpp는 함수형 Component를 생성하여 호출할 준비를 하자.

 

import React from 'react';

const Bpp = () => {
    return (
        <div>
            <h1>Bpp is called!</h1>
        </div>
    );
};

export default Bpp;

 

그리고 App에선 다음과 같이 태그를 추가해주자.

 

import React, { Component } from 'react';
import { Route } from 'react-router-dom';
import Bpp from './Bpp';

class App extends Component {
    render() {
        return (
            <div>
                <h1>App is called!</h1>
                <Route path='/' component={Bpp}/>
            </div>
        );
    }
}

export default App;

 

그러면 React의 기본 접근 경로로 접속하면 다음과 같은 결과가 출력된다.

이번엔 함수형 Component Cpp를 생성하자.

그리고 path에 /Cpp로 지정하여 접근해보자.

 

import React, { Component } from 'react';
import { Route } from 'react-router-dom';
import Bpp from './Bpp';
import Cpp from './Cpp';

class App extends Component {
    render() {
        return (
            <div>
                <h1>App is called!</h1>
                <Route path='/' component={Bpp}/>
                <Route path='/Cpp' component={Cpp}/>
            </div>
        );
    }
}

export default App;

분명히 경로를 Cpp로 했는데 Bpp도 같이 출력됐다.

그 이유는 React는 경로 '/tiger'의 하위 경로인 '/'까지 같이 인식했기 때문에 같이 출력된 것이다.

이러한 문제를 해결해주기 위해 exact 속성을 추가해줘야 한다.

 

import React, { Component } from 'react';
import { Route } from 'react-router-dom';
import Bpp from './Bpp';
import Cpp from './Cpp';

class App extends Component {
    render() {
        return (
            <div>
                <h1>App is called!</h1>
                <Route exact path='/' component={Bpp}/>
                <Route exact path='/Cpp' component={Cpp}/>
            </div>
        );
    }
}

export default App;

 

그러면 Cpp경로로 접근했을 때 Bpp는 호출이 안된 것을 알 수 있다.

 

또한 react-router-dom은 URL에 임의로 입력한 데이터를 가져올 수 있는 기능도 가지고 있다.

이번엔 App Router에 Dpp를 전환하기 위해 다음의 태그를 추가하자.

 

<Route exact path='/Dpp/:pn' component={Dpp}/>

 

특이한 점은 Dpp 경로 뒤에 :pn을 적어줬다.

만약 localhost:3000/Dpp/tiger 를 입력하면, pn에 tiger가 포함된 객체 정보를 반환하게 된다.

pn 데이터를 가져오기 위해 Dpp는 다음과 같이 작성해주자.

 

import React from 'react';

const Dpp = ({match}) => {
    console.log(match);
    
    return (
        <div>
            <h1>Dpp is called!</h1>   
        </div>
    );
};

export default Dpp;

 

Dpp는 props를 통해 가져오는 것이 아니라 match 변수를 통해 받아온다.

Dpp/tiger로 접속하여 console로 로그가 어떻게 뜨는지 확인해보자.

 

그러면 params에 객체 형태로 tiger가 넘어온 걸 알 수 있다.

tiger를 가져올 땐, match.params.pn을 통해 직접 가져올 수 있다.

 

이번엔 JSP에서 URL로 데이터 인자를 넘겼던 방식을 활용하여 데이터를 가져와보자.

Main에는 다음과 같이 Route태그를 추가하자.

 

<Route exact path='/Epp' component={Epp}/>

 

path 뒤에 별 다른 키워드를 사용하진 않았다.

Epp도 함수형 Component를 생성한다.

이번에 Epp로 접근할 땐 다음과 같이 접근해보자.

 

http://localhost:3000/Epp/?name=tiger&age=27

 

별다른 에러 없이 접근이 가능할 것이다.

그럼 뒤에 있는 name과 age는 어떻게 받아올까?

그때 사용하는 것이 location 변수다.

Epp의 인자로 location을 받아와 로그를 출력해보자.

 

import React from 'react';

const Epp = ({location}) => {
    console.log(location);
    
    return (
        <div>
            <h1>Epp is called!</h1>
        </div>
    );
};

export default Epp;

location 변수에는 다음과 같은 객체 정보를 받아온다.

그중 serach key는 ?name=tiger&age=27를 받아온다.

match와 다르게 원하는 정보가 묶여있기 때문에 파싱을 통해 데이터를 가져와야 한다.

위에서 설치했던 Moudle 중 query-string이 있었다.

다음과 같이 import를 해서 parse 함수를 호출하여 파싱을 해보자.

 

import React from 'react';
import qs from 'query-string';

const Epp = ({location}) => {
    console.log(location);

    const n = qs.parse(location.search);
    console.log(n);
    
    return (
        <div>
            <h1>Epp is called!</h1>
        </div>
    );
};

export default Epp;

 

파싱 해온 n을 로그로 출력하면 다음과 같이 객체 형태로 return 될 것이다.

 

그러면 n.age, n.name을 통해 key를 통해 값을 가져올 수 있게 된다.

 

추가로 match와 location 둘 다 동시에 사용할 수 있다.

Fpp를 생성하고 Router 쪽에 다음과 같이 Tag를 추가하자.

 

<Route exact path='/Fpp/:pn' component={Fpp}/>

 

pn을 통해 match 변수를 가져올 수 있을 것이다.

이번엔 location변수까지 같이 사용하기 위해 다음의 경로로 접근을 해보자.

 

http://localhost:3000/Fpp/tiger?name=tiger&age=27

 

그러면 tiger는 match로 받아올 수 있을것이고 ?~부터 location을 통해 가져올 수 있다.

Fpp는 match와 location을 인자로 받아와 동시에 처리하면 된다.

 

import React from 'react';
import qs from 'query-string';

// :방식으로 받아오는 것과 ?로 받아오는 2가지 방식을 했을 때
// match와 location 둘다 인자를 통해서 받아오면 된다.
const Fpp = ({match, location}) => {
    console.log(match.params.pn);

    const n = qs.parse(location.search);
    console.log(n.age);
    console.log(n.name);
    
    return (
        <div>
            <h1>Fpp is called!</h1>
        </div>
    );
};

export default Fpp;

 

Link

말 그대로 link를 걸어준다. 미리 경로를 설정하고 link 태그에 존재하는 to속성을 이용하여 접근할 수 있다.

react-router-dom Module로부터 Link를 import 시켜주자. 그리고 다음과 같이 사용하면 된다.

 

<Link to={경로}></Link>

 

경로는 아까 Fpp에서 입력했던 경로를 미리 잡아주면 된다.

 

<Link to='/Fpp/tiger?name=tiger&age=27'>Go to Fpp!</Link>

 

import React, { Component } from 'react';
import { Route, Link } from 'react-router-dom';
import Bpp from './Bpp';
import Cpp from './Cpp';
import Dpp from './Dpp';
import Epp from './Epp';
import Fpp from './Fpp';

class App extends Component {
    render() {
        return (
            <div>
                <h1>App is called!</h1>
                <Route exact path='/' component={Bpp}/>
                <Route exact path='/Cpp' component={Cpp}/>
                <Route exact path='/Dpp/:pn' component={Dpp}/>
                <Route exact path='/Epp' component={Epp}/>
                <Route exact path='/Fpp/:pn' component={Fpp}/>
                <Link to='/Fpp/tiger?name=tiger&age=27'>Go to Fpp!</Link>
            </div>
        );
    }
}

export default App;

 

그러면 다음과 같은 파란 글이 나올 것이다.

클릭하면 Fpp로 위의 경로와 같이 자동으로 이동하게 된다.

 

Button 태그를 감싸서 버튼 형식으로 만들수도 있다.
<Link to={경로}><button>Click!</button></Link>