공부블로그

리액트 Router DOM 사용하기 본문

리액트/리액트 공부

리액트 Router DOM 사용하기

떠어영 2021. 8. 1. 02:27

  Routing : URL에 따라서 적당한 콘텐츠를 전송해주는 것

 

< 내가 정리한 Router DOM 사용법 >

 

  • BrowserRouter는 최상위 컴포넌트를 감싸주어 BrowserRouter를 사용가능하도록 해준다. 
  • url에 따라 달라져야하는 컴포넌트에 Route로 감싸주고 path지정
  • Link : 페이지가 바뀌지 않고 링크로 이동
  • NavLink : 클릭 시 해당 a태그에 active class생성 => css의 .active로 스타일 변경가능

 

◎ 기본 작업

 

create-react-app 을 통해 새로운 프로젝트를 생성하고 npx install react-router-dom 을 통해 라우팅 도구 설치 후,

import { BrowserRouter, Route, Switch, Link, NavLink ,useParams } from 'react-router-dom'

. . .

ReactDOM. render(<BrowserRouter></app ></BrowserRouter>,document.getElementById('root'));

BrowserRouter는 최상위 컴포넌트를 감싸주어 BrowserRouter를 사용가능하도록 해준다.

 

 

◎ 라우팅 

 

App 컴포넌트에서 항목을 클릭하면 url이 바뀌며, 그 주소에 해당되는 컴포넌트가 라우팅되도록 작성!

 

a href=' ' 와 유사한 기능을 가진 Link to=' ' 사용하여 각 항목을 눌렀을 때 이동할 주소를 명시해준다. ( Link 사용시에는 페이지가 바뀌지 않는다. )

<li> <NavLink exact to=' / '> Home </NavLink> </li>

달라진 주소에 보이고 싶은 컴포넌트를 지정하기 위해 보여줄 컴포넌트를 Route로 감싸주고 그에 맞는 path 작성

<Route exact path="/"><Home/></Route> 

이 때, Switch 와 exact 등을 사용하여 더욱 정교하게 구현할 수 있다. 

 

 

◎ 배열을 이용한 라우팅

 

전역변수로 contents 라는 객체 배열을 생성한다. ( 객체는 id, title, description 을 가지고 있음 )

Topics 컴포넌트에서는 for문으로 contents 리스트의 id와 title을 이용하여 NavLink to=' ' 를 가진<li>태그 리스트를 만들어 <ul>태그 사이에 작성한다.

그 아래에는 < Route path=' /topics/ : topic_id' > <Topic/> </Route>를 작성하여 topic_id라는 동적 라우팅값을 걸어주었다. 

(  하나의 라우터로 인자를 받기 위한 변수(id)를 설정해주면 해당 자리에 들어오는 숫자가 Topic컴포넌트로 전달되고, useParams Hooks를 사용해 숫자를 가져와 동적으로 동작하는 페이지 생성 가능 )

따라서, Topic 컴포넌트는 params라는 변수를 만들어 useParams( ) Hooks로 path parameter의 정보를 얻어온다.

topic_id = params. topic_id; 

반복문을 돌아가면서 contents의 id가 params. topic_id와 같으면 selected_topic을 해당 인덱스의 contents값으로 설정.

return 값에 선택된 항목의 제목과 설명을 div태그로 감싸서 반환한다. 

 

 

( index. js 코드 )

import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import {BrowserRouter, Route, Switch, Link, NavLink ,useParams} from 'react-router-dom';

//1. BrowserRouter는 최상위 컴포넌트를 감싸주어 BrowserRouter를 사용가능하도록 해준다.
//2. url에 따라 달라져야하는 컴포넌트에 Route로 감싸주고 path지정
//3. Link : 페이지가 바뀌지 않고 링크로 이동
//4. NavLink : 클릭 시 해당 a태그에 active class생성 => css의 .active로 스타일 변경가능

function Home(){
  return(
    <div>
      <h2>Home</h2>
      home...
    </div>
  )
}
var contents = [ //전역변수 잭체 배열 생성
  {id: 1, title: 'HTML', description: 'HTML is...'},
  {id: 2, title: 'JavaScript', description: 'JavaScript is...'},
  {id: 3, title: 'React', description: 'React is...'},
]

function Topic(){
  var params = useParams(); 
  // useParams는 path parameter의 정보를 얻을 수 있는 hooks (params: {topic_id: "1"}객체)
  var topic_id = params.topic_id; // params객체의 topic_id값
  var selected_topic = { title: 'Sorry', description: 'Not found'} // default값도 설정해줌

  for(var i =0; i<contents.length; i++){
    if(contents[i].id === Number(topic_id)){
      selected_topic = contents[i];
      break;
    }
  }
  return (
    <div>
      <h3>{selected_topic.title}</h3>
      {selected_topic.description}
    </div>
  )
}

function Topics(){

  var list = []; //리스트 만들어서 편리하게 <li>태그 생성

  for(var i= 0; i< contents.length; i++){
    list.push(<li key={contents[i].id}><NavLink to={'/topics/'+ contents[i].id}>{contents[i].title}</NavLink></li>);
  }
  return(
    <div>
      <h2>Topics</h2>
        <ul>
          {list}
        </ul>
          <Route path="/topics/:topic_id">
            {/* topic_id라는 동적 라우팅값을 걸어주었다. 
            하나의 라우터로 parameter를 받기 위한 변수(id)를 설정해주면 해당 자리에 들어오는 숫자가 
            Topic컴포넌트로 전달되고, useParams Hooks를 사용해 가져와 동적으로 동작하는 페이지 생성 가능
            */}
            <Topic/>
          </Route>
          {/*<Switch>
            <Route path="/topics/1">HTML is ...</Route>
            <Route path="/topics/2">JavaScript is ...</Route>
            <Route path="/topics/3">React is ...</Route>
          </Switch>*/}
    </div>
  )
}
function Contact(){
  return(
    <div>
      <h2>Contact</h2>
      contact...
    </div>
  )
}
function App(){ //index.js 안에서 직접 App component를 만들어서 render
  return(
  <div>
  <h1>React Router DOM example</h1>
  <ul>
    <li><NavLink exact to='/'>Home</NavLink></li> {/*누르면 해당 링크로 이동 ( a href='' 대신 (Nav)Link to=''사용 )*/}
    <li><NavLink to='/topics'>topics</NavLink></li> {/* Link => 페이지가 바뀌지 않고 링크로 이동*/}
    <li><NavLink to='/contact'>contact</NavLink></li>
  </ul>
    <Switch>
      <Route exact path="/"><Home/></Route> {/*최상위 링크에 접근하면 Home컴포넌트를 라우팅*/}
      <Route path="/topics"><Topics/></Route> {/*http://localhost:3001/topics에 접근하면 Home컴포넌트를 라우팅*/}
      <Route path="/contact"><Contact/></Route> {/*http://localhost:3001/contact에 접근하면 Home컴포넌트를 라우팅*/}
      <Route path="/"><b>Not Found</b></Route> {/*url이 잘못되엇을 때*/}
    </Switch>
  </div>
  )
}

ReactDOM.render(<BrowserRouter><App /></BrowserRouter>,document.getElementById('root'));