yarn add react-router-dom@^5.3.0
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import {BrowserRouter} from "react-router-dom";
ReactDOM.render(
<BrowserRouter>
<App />
</BrowserRouter>,
document.getElementById('root')
);
//Home
import React from 'react';
const Home=()=>{
return (
<div>
<h1>홈</h1>
<p>홈, 그 페이지는 가장 먼저 보이는 페이지</p>
</div>
)
}
export default Home;
//About
import React from 'react';
const About = ()=>{
return (
<div>
<h1>소개</h1>
<p>이 프로젝트는 리액트 라우터 기초를 실습해보는 예제</p>
</div>
)
}
export default About;
어떤 규칙을 가진 경로에 어떤 컴포넌트 보여줄지 정의
<Route path="주소 규칙" component={보여 줄 컴포넌트}>
import React from "react";
import { Route,Link } from "react-router-dom";
import Home from "./components/Home";
import About from './components/About';
const App = () => {
return (
<div>
<Route path="/" component={Home} exact={true} />
<Route path="/about" component={About}/>
</div>
);
};
export default App;
path="/"
에 exact={true}
를 설정해야 /로 시작하는 라우팅과 겹치지 않음exact=true 설정하지 않고 /about으로 페이지 이동을 한 경우 /와 /about로 설정한 것 동시에 등장
<Link to="주소">내용</Link>
import React from "react";
import { Route,Link } from "react-router-dom";
import Home from "./components/Home";
import About from './components/About';
const App = () => {
return (
<div>
<ul>
<li><Link to="/"> 홈</Link></li>
<li><Link to="/about">about</Link></li>
</ul>
<Route path="/" component={Home} exact={true} />
<Route path="/about" component={About}/>
</div>
);
};
export default App;
홈 클릭 | about 클릭 |
---|---|
/about
과 /info
모두 about 페이지로 가도록 한 번에 path 설정import React from "react";
import { Route,Link } from "react-router-dom";
import Home from "./components/Home";
import About from './components/About';
const App = () => {
return (
<div>
<ul>
<li><Link to="/"> 홈</Link></li>
<li><Link to="/about">about</Link></li>
</ul>
<Route path="/" component={Home} exact={true} />
<Route path={["/about","/info"]} component={About}/>
</div>
);
};
export default App;
/profiles/:username
일 때, match.params.username
을 사용해 파라미터인 username값 조회 가능import React from 'react';
const data={
velopert:{
name:"김민준",
description :"리액트를 좋아하는 개발자"
},
gildong:{
name:"홍길동",
description:"고전 소설 주인공"
}
};
const Profile=({match})=>{
const {username}=match.params;
//path 규칙에서 파라미터인 username 부분 받아오기
const profile=data[username];
if(!profile){
return <div>존재하지 않는 사용자임</div>
}
return (
<div>
<h3>{username}({profile.name})</h3>
<p>{profile.description}</p>
</div>
);
};
export default Profile;
import React from "react";
import { Route,Link } from "react-router-dom";
import Home from "./components/Home";
import About from './components/About';
import Profile from './components/Profile';
const App = () => {
return (
<div>
<ul>
<li><Link to="/"> 홈</Link></li>
<li><Link to="/about">about</Link></li>
<li><Link to="/profile/velopert">velopert 프로필</Link></li>
<li><Link to="/profile/gildong">gildong 프로필</Link></li>
</ul>
<Route path="/" component={Home} exact={true} />
<Route path={["/about","/info"]} component={About}/>
<Route path="/profile/:username" component={Profile}/>
</div>
);
};
export default App;
쿼리 문자열을 객체로 변환하는 라이브러리 설치
yarn add qs
숫자 (?value=1) 또는 논리 자료형 (boolean) 사용 시 문자열 형태로 받아짐
숫자는 parseInt 사용해 변환 & 논리 자료형 값 사용해 "true"와 일치하는 지 확인
import React from 'react';
import qs from "qs";
const About =({location})=>{
const query=qs.parse(location.search,{
ignoreQueryPrefix:true // 이 설정을 통해 문자열 맨 앞의 ? 생략
});
const showDetail=query.detail==="true"
//쿼리의 파싱 결과 값는 문자열
return(
<div>
<h1>소개</h1>
<p>이 프로젝트는 리액트 라우터 기초를 실습해보는 예제</p>
{showDetail&&<p>detail 값을 true로 설정</p>}
</div>
);
};
export default About;
App.js
import React from "react";
import { Route, Link } from "react-router-dom";
import About from "./components/About";
import Home from "./components/Home";
import Profiles from "./components/Profiles";
const App = () => {
return (
<div>
<ul>
<li>
<Link to="/">HOME</Link>
</li>
<li>
<Link to="/about">ABOUT</Link>
</li>
<li>
<Link to="/profiles">프로필</Link>
</li>
</ul>
<Route path="/" component={Home} exact={true} />
<Route path={["/about", "/info"]} component={About} />
<Route path="/profiles" component={Profiles} />
/*Profiles 컴포넌트를 /profiles 경로에 연결*/
</div>
);
};
export default App;
Profiles.js
import React from "react";
import { Link, Route } from "react-router-dom";
import Profile from "./Profile"
const Profiles = () => {
return (
<div>
<h3>사용자 목록:</h3>
<ul>
<li>
<Link to="/profiles/velopert">velopert</Link>
</li>
<li>
<Link to="/profiles/gildong">gildong</Link>
</li>
</ul>
<Route path="/profiles" exact render={()=><div>사용자를 선택해 주세요</div>}/>
<Route path="/profiles/:username" component={Profile}/>
</div>
);
};
export default Profiles;
HistorySample.js
import React,{Component} from 'react';
class HistorySample extends Component{
//뒤로 가기
handleGoBack=()=>{
this.props.history.goBack();
}
//홈으로 이동
handleGoHome=()=>{
this.props.history.push("/");
}
//설정 후 페이지에 변화 생기려고 할 때마다 정말 나갈 것인지 질문
componentDidMount(){
this.unblock=this.props.history.block("정말 떠나실 건가요?")
}
//컴포넌트가 언마운트되면 질문을 멈춤
componentWillUnmount(){
if(this.unblock){
this.unblock();
}
}
render(){
return(
<div>
<button onClick={this.handleGoBack}>뒤로</button>
<button onClick={this.handleGoHome}>홈으로</button>
</div>
)
}
}
export default HistorySample;
App.js
import React from "react";
import { Route, Link } from "react-router-dom";
import About from "./components/About";
import Home from "./components/Home";
import Profiles from "./components/Profiles";
import HistorySample from './components/HistorySample';
const App = () => {
return (
<div>
<ul>
<li>
<Link to="/">HOME</Link>
</li>
<li>
<Link to="/about">ABOUT</Link>
</li>
<li>
<Link to="/profiles">프로필</Link>
</li>
<li><Link to="/history">History 예제</Link></li>
</ul>
<Route path="/" component={Home} exact={true} />
<Route path={["/about", "/info"]} component={About} />
<Route path="/profiles" component={Profiles} />
<Route path="/history" component={HistorySample}/>
</div>
);
};
export default App;
withRouter(WithRouterSample)
: path="/profiles"
라고만 해서 username 파라미터 읽어온 것 없음withRouter(Profile)
: path="/profiles/:username"
이라고 하여 username 파라미터 읽어옴WithRouterSample.js
import React from 'react';
import { withRouter } from 'react-router-dom';
import Profiles from './Profiles';
const WithRouterSample=({location,match,history})=>{
return (
<div>
<h4>location</h4>
<textarea
value={JSON.stringify(location,null,2)}
rows={7}
readOnly={true}/>
<h4>match</h4>
<textarea
value={JSON.stringify(match,null,3)}
rows={7}
readOnly={true}
/>
<button onClick={()=>history.push("/")}>홈으로</button>
</div>
);
};
export default withRouter(WithRouterSample);
Profile.js
import React from "react";
import { Link, Route } from "react-router-dom";
import Profile from "./Profile"
const Profiles = () => {
return (
<div>
<h3>사용자 목록:</h3>
<ul>
<li>
<Link to="/profiles/velopert">velopert</Link>
</li>
<li>
<Link to="/profiles/gildong">gildong</Link>
</li>
</ul>
<Route path="/profiles" exact render={()=><div>사용자를 선택해 주세요</div>}/>
<Route path="/profiles/:username" component={Profile}/>
</div>
);
};
export default Profiles;
Profiles.js
import React from "react";
import { withRouter } from 'react-router-dom';
import WithRouterSample from './WithRouterSample';
const data = {
velopert: {
name: "백동현",
description: "리액트를 공부하는 학생",
},
gildong: {
name: "홍길동",
description: "고전 소설 홍길동전의 주인공",
},
};
const Profile = ({ match }) => {
console.log(match)
const { username } = match.params;
console.log(username);
const profile = data[username];
if (!profile) {
return <div>존재하지 않는 사용자입니다.</div>;
}
return (
<div>
<h3>
{username}({profile.name})
</h3>
<p>{profile.description}</p>
<WithRouterSample/>
</div>
);
};
export default withRouter(Profile);
import React from "react";
import { Route, Link, Switch } from "react-router-dom";
import About from "./components/About";
import Home from "./components/Home";
import Profiles from "./components/Profiles";
import HistorySample from './components/HistorySample';
const App = () => {
return (
<div>
<ul>
<li>
<Link to="/">HOME</Link>
</li>
<li>
<Link to="/about">ABOUT</Link>
</li>
<li>
<Link to="/profiles">프로필</Link>
</li>
<li><Link to="/history">History 예제</Link></li>
</ul>
<hr/>
<Switch>
<Route path="/" component={Home} exact={true} />
<Route path={["/about", "/info"]} component={About} />
<Route path="/profiles" component={Profiles} />
<Route path="/history" component={HistorySample}/>
{/* path를 따로 정의 하지 않으면 모든 상황에 랜더링됨*/}
<Route render={({location})=>(
<div>
<h2>이 페이지는 존재하지 않습니다.</h2>
<p>{location.pathname}</p>
</div>
)}/>
</Switch>
</div>
);
};
export default App;
import React from "react";
import { NavLink, Route } from "react-router-dom";
import Profile from "./Profile"
const Profiles = () => {
const activeStyle={
//선택되어 있는 경우 적용될 스타일
background:"black",
color:"white"
};
return (
<div>
<h3>사용자 목록:</h3>
<ul>
<li>
<NavLink
activeStyle={activeStyle}
to="/profiles/velopert">velopert</NavLink>
</li>
<li>
<NavLink
activeStyle={activeStyle}
to="/profiles/gildong">gildong</NavLink>
</li>
</ul>
<Route path="/profiles" exact render={()=><div>사용자를 선택해 주세요</div>}/>
<Route path="/profiles/:username" component={Profile}/>
</div>
);
};
export default Profiles;