반응형
SPA란?
- SPA는 Single Page Application(싱글 페이지 애플리케이션)의 약어입니다.
- 말 그대로 한 개의 페이지로 이루어진 애플리케이션이라는 의미입니다.
- 전통적인 웹 페이지는 다음과 같이 여러 페이지로 구성되어 있습니다.
기존방식
- 다른 페이지로 이동할 때 마다 새로운 html, 페이지 로딩 시 서버에서 리소스 전달받아 해석한 뒤 화면 보여줌
- 사용자에게 보이는 화면은 서버 측에서 준비.
- 유동적인 html 생성해주는 템플릿 엔진 사용
- 서버 측에서 모든 뷰를 준비한다면 성능상의 문제가 발생
- 바뀌지 않은 부분까지 새로 불러와 불필요한 로딩이 있어 비효율적
Single Page Application: 말 그대로 한 개의 페이지로 이루어진 애플리케이션
- 뷰 렌더링을 사용자의 브라우저가 담당.
- 애플리케이션을 브라우저에 불러와서 실행시킨 후 사용자와의 인터랙션이 발생하면 필요한 부분만 자바스크립트를 이요하여 업데이트
- 새로운 데이터가 필요하다면 서버 API를 호출하여 필요한 데이터만 새로 불러와 애플리케이션을 사용할 수 있다.
라우팅
- 다른 주소에 다른 화면을 보여 주는 것
- 싱글 페이지라고 해서 화면이 한 종류는 아니다. 해당 페이지에서 로딩된 자바스크립트와 현재 사용자 브라우저의 주소 상태에 따라 다양한 화면을 보여 줄 수 있다.
- 리액트 라우팅 라이브러리
- 리액트 라우터
- Next.js
SPA의 단점
- SPA의 단점은 앱의 규모가 커지면 자바스크립트 파일이 너무 커진다는 것입니다.
- 페이지 로딩 시 사용자가 실제로 방문하지 않을 수도 있는 페이지의 스크립트도 불러오기 때문
- 리액트 라우터처럼 브라우저에서 자바스크립트를 사용하여 라우팅을 관리하는 것은 자바스크립트를 실행하지 않는 일반 크롤러에서는 페이지의 정보를 제대로 수집해 가지 못한다는 잠재적인 단점이 있다.
- 구글, 네이버, 다음 같은 검색 엔진의 검색 결과에 페이지가 잘 나타나지 않을 수도 있습니다.
- 자바스크립트가 실행될 때까지 페이지가 비어 있기 때문에 자바스크립트 파일이 로딩되어 실행되는 짧은 시간 동안 흰 페이지가 나타날 수 있다는 단점도 있습니다.
- 이러한 문제점들은 다행히 나중에 배우게 될 서버 사이드 렌더링(server-side rendering)을 통해 모두 해결할 수 있습니다.
프로젝트 설치, 라이브러리 설치
- 해당 디렉토리에 yarn add react-router-dom
프로젝트에 적용
- 프로젝트에 리액트 라우터를 적용할 때는 src/index.js 파일에서 react-router-dom에 내장되어 있는 BrowserRouter라는 컴포넌트를 사용하여 감싸면 됩니다.
- 이 컴포넌트는 웹 애플리케이션에 HTML5의 History API를 사용하여 페이지를 새로고침하지 않고도 주소를 변경하고, 현재 주소에 관련된 정보를 props로 쉽게 조회하거나 사용할 수 있도록 해 줍니다.
라우팅 구현
- 처음 보여줄 Home 컴포넌트 생성, 웹 사이트를 소개하는 About 컴포넌트 생성
- Router 컴포넌트 사용해 현재 경로에 따라 다른 컴포넌트 렌더링
- 규칙 : <Route path="주소 규칙" component={보여 줄 컴포넌트}>
// App.js
import About from './About'
import Home from './Home'
import {Route} from 'react-router-dom'
...
return (
<div>
<Route path='/' component={HOME}>
<Route path='/about' component={ABOUT}>
</div>
)
/가 겹치는 문제
- 이 경우 about 페이지에 HOME 컴포넌트도 함께 렌더링 된다.
- /about 경로가 / 규칙에도 일치하기 때문
- Home 위한 Route 컴포넌트를 사용할 때 exact라는 props를 true로 설정
- <Route path='/' component={HOME} exact={true}>
Link 컴포넌트를 사용하여 다른 주소로 이동하기
- Link 컴포넌트는 클릭하면 다른 주소로 이동시켜 주는 컴포넌트입니다.
- 일반 웹 애플리케이션에서는 a 태그를 사용하여 페이지를 전환하는데요.
- 리액트 라우터를 사용할 때는 이 태그를 직접 사용하면 안 됩니다.
- 이 태그는 페이지를 전환하는 과정에서 페이지를 새로 불러오기 때문에 애플리케이션이 들고 있던 상태들을 모두 날려 버리게 됩니다.
- 렌더링된 컴포넌트들도 모두 사라지고 다시 처음부터 렌더링하게 되죠.
- Link 컴포넌트를 사용하여 페이지를 전환하면, 페이지를 새로 불러오지 않고 애플리케이션은 그대로 유지한 상태에서 HTML5 History API를 사용하여 페이지의 주소만 변경해 줍니다.
- Link 컴포넌트 자체는 a 태그로 이루어져 있지만, 페이지 전환을 방지하는 기능이 내장되어 있습니다.
<Link to="주소">내용</Link>
return (
<div>
<ul>
<li>
<Link to="/">홈</Link>
</li>
<li>
<Link to="/about">소개</Link>
</li>
</ul>
<Route path='/' component={Home}>
<Route path='/about' component={About}>
</div>
)
Route 하나에 여러 개의 path 설정하기
// Route 하나당 컴포넌트 설정
<Route path='/' component={Home} exact={true}>
<Route path='/about' component={About}>
<Route path='/info' component={About}>
// Route 하나에 여러 path 설정
<Route path='/' component={Home} exact={true}>
<Route path={['/about', '/info']} component={About}>
URL 파라미터와 쿼리
- 페이지 주소를 정의할 때 가끔은 유동적인 값을 전달해야 할 때도 있습니다.
- 이는 파라미터와 쿼리로 나눌 수 있습니다.
- 파라미터 예시: /profiles/velopert
- 쿼리 예시: /about?details=true
- 유동적인 값을 사용해야 하는 상황에서 파라미터를 써야 할지 쿼리를 써야 할지 정할 때, 무조건 따라야 하는 규칙은 없습니다.
- 다만 일반적으로 파라미터는 특정 아이디 혹은 이름을 사용하여 조회할 때 사용하고, 쿼리는 우리가 어떤 키워드를 검색하거나 페이지에 필요한 옵션을 전달할 때 사용합니다.
URL 파라미터
- 뒷부분에 유동적인 username 값을 넣어 줄 때 해당 값을 props로 받아 와서 조회하는 방법
- App.js
- Route path의 /:username을 통해 Profile 컴포넌트에 props를 전달한다.
- 이 때 Link에 있는 /velopert, /dongwon이 username 값으로 Profile 컴포넌트에 props에 전달
- <li><Link to="/profile/velopert">velopert 프로필</Link></li><li><Link to="/profile/dongwon">dongwon 프로필</Link></li><Route path="/profile/:username" component={Profile} />
- Profile.js
const Profile = ({ match }) => { const { username } = match.params; const profile = data[username]; if (!profile) { return <div> 존재하지 않는 사용자입니다.</div>; } return ( <div><h3> {username}({profile.name}) </h3><p>{profile.description}</p></div> ); };
- App.js 에서 전달받은 props : match.params.username = velopert 혹은 dongwon
- const data = { velopert: { name: '김민준', description: '리액트 저자', }, dongwon: { name: '김동원', description: '공부 중', }, };
URL 쿼리
- location 객체
- location 객체 안의 search값에서 쿼리 조회 가능
- 라우트로 사용된 컴포넌트에게 props로 전달.
- 웹 애플리케이션의 현재 주소에 대한 정보를 가지고 있다.
- localhost:3000/about?detail=true 주소 일 때
{ "pathname": "/about", "search": "?detail=true" "hash" : "" }
- 문자열 형태로 이루어져 있다. 특정 값을 불러오기 위해 문자열을 객체 형태로 변환
- qs 라이브러리.
- yarn add qs
- About.js
- localhost:3000/about?detail=true 로 들어갔을 때
const query = qs.parse(location.search, { ignoreQueryPrefix: true, }); const showDetail = query.detail === 'true';
- ignoreQueryPrefix: true, 를 통해 앞의 ?를 제거
- query는 "detail=true"
서브 라우트
- 서브 라우트는 라우트 내부에 또 라우트를 정의하는 것을 의미합니다.
- 이 작업은 그렇게 복잡하지 않습니다.
- 그냥 라우트로 사용되고 있는 컴포넌트의 내부에 Route 컴포넌트를 또 사용하면 됩니다.
리액트 라우터 부가 기능
history - 클래스형 컴포넌트
- history 객체
- 컴포넌트에 match, location과 함께 전달되는 props 중 하나
- 컴포넌트 내에 구현하는 메서드에서 라우터 API 호출 가능
- ex) 뒤로가기, 화면 전환, 다른 페이지 이탈 방지
withRouter 컴포넌트
- 라우터로 사용된 컴포넌트가 아니어도 match, location, history 사용 가능
- 주소 경로가 없는 컴포넌트도 사용이 가능하다.
- 라우트 기능이 없지만 withRouter를 사용하여 location, match, history 사용
- textarea를 통해 location, match를 확인. 버튼을 이용해 histroy 기능 확인 가능하다.
- export 할 때 withRouter(WithRouterSample)로 감싸준다.
- match객체의 param은 현재 자신을 보여 주고 있는 라우트 컴포넌트를 기준으로 match가 전달.
- Profile과 Profiles에 넣어보고 비교
Switch 컴포넌트
- 여러 Route를 감싸서 그 중 일치하는 단 하나의 라우터만 렌더링
- 모든 규칙과 일치하지 않을 때 Not Found 페이지도 구현 가능
NavLink
- 현재 경로와 Link에서 사용하는 경로가 일치하는 경우 특정 스타일, CSS 클래스를 적용할 수 있는 컴포넌트
- NavLink가 활성화되어 스타일을 적용할 때는 activeStyle을, CSS 클래스를 적용할 때는 activeClassName을 props로 넣어 준다.
반응형
'react를 다루는 기술' 카테고리의 다른 글
15. Context API (0) | 2022.06.17 |
---|---|
14. 외부 API를 연동하여 뉴스 뷰어 만들기 (0) | 2022.06.16 |
12. immer를 사용하여 더 쉽게 불변성 유지하기 (0) | 2022.06.14 |
11. 컴포넌트 성능 최적화 (0) | 2022.06.13 |
10. 일정 관리 웹 애플리케이션 만들기 (0) | 2022.06.11 |