URL 쿼리
이번에는 About 페에지에서 쿼리를 받아 오겠습니다. 쿼리는 location 객체에 들어 있는 search 값에서 조회할 수 있다. location 객체는 라우트로 사용된 컴포넌트에게 props로 전달되며, 웹 어플리케이션의 현재 주소에 대한 정보를 지니고 있다. location의 형태는 다음과 같다.
{
"pathname": "/about",
"search": "?detail=true",
"hash": " "
}
위 location 객체는 URL/about?deatail=true 주소로 들어갔을 때의 값이다. URL 쿼리를 읽을 때는 위 객체가 지닌 값 중에서 search 값을 확인해야 한다. 이 값은 문자열 형태로 되어 있다. 또한 URL 쿼리는 ?detail=true&another=1과 같이 문자열에 여러 가지 값을 설정해 줄 수 있다. search 값에서 특정 값을 읽어 오기 위해서는 이 문자열을 객체 형태로 변환해 주어야 한다.
쿼리 문자열을 객체로 변환할 때는 qs라는 라이브러리를 사용한다. yarn을 통해 해당 라이브러리를 설치해보자.
$ yarn add qs
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;
쿼리를 사용할 때는 쿼리 문자열을 객체로 파싱하는 과정에서 결과 값은 항상 문자열이라는 점에 주의하자. ?value=1 혹은 ?value=true와 같은 값을 전달 받아도 파싱 후 "1", "true"와 같이 문자열 형태로 받아진다.
그렇기 때문에 숫자를 받는 경우는 parseInt 함수를 통해 꼭 숫자로 변환해 주고, 논리 자료형 값인 경우에는 "true"문자열과 비교하여 사용하자.
서브 라우트
서브 라우트는 라우트 내부에 또 라우트를 정의하는 것을 의미한다. 이 작업은 그냥 라우트로 사용되고 있는 컴포넌트의 내부에 Route 컴포넌트를 또 사용하면 된다.
profiles라는 라우트 컴포넌트를 따로 만들고, 그 안에서 profile 컴포넌트를 서브 라우트로 사용하도록 코드를 작성해 보겠다.
import React from 'react';
import {Link, Route} from 'react-router-dom';
import Profile from './Profile';
const Profiles = () => {
return(
<div>
<ul>
<li>
<Link to="/profiles/seyoung8239">seyoung</Link>
</li>
<li>
<Link to="/profiles/asdf">mandoo</Link>
</li>
</ul>
<Route
path="/profiles"
exact
render={()=><div>사용자를 선택해 주세요.</div>}
/>
<Route path="/profiles/:username" component={Profile}/>
</div>
)
}
export default Profiles;
리액트 라우터 부가 기능
history
history 객체는 라우트로 사용된 컴포넌트에 match, location과 함께 전달되는 props 중 하나로, 이 객체를 통해 컴포넌트 내에 구현되는 메서드에서 라우터 API를 호출할 수 있다. 예를 들어 뒤로가기 버튼, 로그인 후 화면 전환, 다른 페이지로의 이탈 방지를 구현할 때 history를 이용한다
import React, {Component} from 'react';
class HistorySample extends Component {
hadnleGoBack = () => {
this.props.history.goBack();
};
hadnleGoHome = () => {
this.props.history.push('/');
};
componentDidMount = () => {
this.unblock = this.props.history.block('정말 떠나실 건가요?');
};
componentDidMount() {
if(this.unblock)
this.unblock();
}
render() {
return(
<div>
<button onClick={this.hadnleGoBack}뒤로></button>
<button onClick={this.hadnleGoHome}>홈으로</button>
</div>
);
}
}
export default HistorySample;
withRouter
withRouter 함수는 HoC(higher-order Component)이다. 라우트로 사용된 컴포넌트가 아니어도 match, location, history 객체를 접근할 수 있게 해 준다.
import React from 'react';
import {withRouter} from 'react-router-dom';
const WithRouterSample = ({location, match, history}) => {
return(
<div>
<h4>location</h4>
<textarea
value={JSON.stringify(location, null, 2)}
rows={7}
readOnly
/>
<h4>match</h4>
<textarea
value={JSON.stringify(match, null, 2)}
rows={7}
readOnly
/>
<button onClick={()=>history.push('/')}>홈으로</button>
</div>
);
}
export default withRouter(WithRouterSample);
JSON.stringify의 두 번째 파라미터와 세 번째 파라미터를 위와 같이 null, 2로 설정해 주면 JSON에 들여쓰기가 적용된 상태로 문자열이 만들어진다.
Switch
switch컴포넌트는 여러 Route를 감싸서 그중 일치하는 단 하나의 라우트만 렌더링 시켜준다. swtich를 사용하면 모든 case와 일치하지 않을 때 보여 줄 Not Found 페이지도 구현 가능하다.
<Switch>
<Route path="/" component={Home} exact={true}/>
<Route path={['/about', '/info']} component={About}/>
<Route path='/profiles' component={Profiles}/>
<Route path='/history' component={HistorySample}/>
<Route
render={({location})=>(
<div>
<h2>이 페이지는 존재하지 않습니다:</h2>
{location.pathname}
</div>
)}
/>
</Switch>
NavLink
NavLink는 Link와 비슷하다. 현재 경로와 Link에서 사용하는 경로가 일치하는 경우 특정 스타일 혹은 CSS 클래스를 적용할 수 있는 컴포넌트이다.
NavLink에서 링크가 활성화되었을 때의 스타일을 적용할 때는 activeStyle 값을, CSS 클래스를 적용할 때는 activeClassName 값을 props로 넣어주면 된다.
'Frontend > React' 카테고리의 다른 글
2021-05-06 :: Todo Project1 (0) | 2021.05.06 |
---|---|
2021-05-03 :: 리액트 라우터로 SPA 개발하기3 (0) | 2021.05.03 |
2021-04-23 :: 리액트 라우터로 SPA 개발하기 (0) | 2021.04.27 |
2020-04-08 :: ref: DOM에 이름 달기 (0) | 2021.04.08 |
2021-04-05 :: Hooks2 (0) | 2021.04.06 |