728x90
📍 54일 차 1.7. 금. 온라인 강의
오늘은 SPA, MPA, React-router-dom 속성에 대해서 배웠다. 이후에 useReducer를 사용해 문제를 푸는데 useReducer를 사용해본적이 많지 않아 난이도가 조금 어렵게 느껴졌다.
❏ SPA(Single Page Application)
- 하나의 페이지 요청으로 전체 웹앱을 사용하는 방식
- 유저는 웹페이지를 사용하며 모바일 앱 같은 경험을 느낌(새 로고 침 없이 화면 전환이 된다.)
html코드를 읽다가script태그를 만나면 다시 서버에 요청하고 서버에서 다시 브라우저로 넘겨준다. 브라우저에서JS코드를 파싱한 다음app.js가 렌더링된다.CSR기술을 활용하여, 페이지 진입 시 리로드 없이 라우팅 한다.AJAX기술을 활용, 페이지 이동 시 서버에 데이터만 요청하여JS로 페이지를 만듦 (fetch등..)MPA와 다르게 여러 페이지를 하나의 앱의 구성요소로 보고 여러 페이지 간의 스타일, 컴포넌트를 재활용하는 방향으로 구현한다.JS만으로 전체 페이지를 만들기 때문에, 첫 요청 시 빈 페이지를 받게 된다.
장점
- 서버에서 페이지를 만들 필요가 없으므로 CDN에 캐싱이 가능하다.
* CDN:콘텐츠 전송 네트워크(contents network delivery), 서버가 각 최종 사용자들에게 가장 가까운 서버를 기반으로 데이터 요청을 수행한다.
* 더 빠른 서비스 제공 가능(HTML, CSS, JS 등...)
- 매번 페이지 요청을 할 필요가 없어 네트워크 요청이 줄어듦(서버 입장), 마찬가지로, 데이터 요청 등을 캐싱하여 재사용하는 등 제약 조건이 줄어듦
- 웹 사이트를 개별 페이지보다는 하나의 앱으로 보는 설계로 고도의 S/W 설계와 패턴을 적용할 수 있음
단점
- MPA 방식보다는 SEO에 불리함
- 하나의 JS 앱이 지속하므로, 메모리 관리, 성능, 데이터 활용 등이 중요하다.
- 모든 페이지를 한번에 로드해야 하므로 코드가 많아질수록 로드 속도가 느려진다.
❏ MPA(Multi Page Application)
- 서버에 미리 여러 페이지를 두고 유저가 내비게이션 요청 시 요청에 적합한 페이지를 전달한다.
- 미리 서버에서 전체 페이지를 빌드해 브라우저로 전송된다.
- 서버에 라우팅을 처리하는 기능이 있고, 서버에서 여러 페이지를 관리한다.
- 페이지 요청마다 모든 리소스를 다시 받아오므로, 페이지 간 데이터를 재활용하기 힘듦
res.send(page)를 받으면build된 페이지를 브라우저로 전달해준다.- MPA는 서버에서 build 하기 때문에 CDN처리를 할 수 없다.
❏ SPA에서 라우팅이 중요한 이유
- 주로
History API혹은URL Hash(www.naver.com#a, #b, #c ,,,)를 이용해 페이지 리로드 없는 페이지 전환을 구현한다. history,location등HTML5 API를 활용한다.visibilitychange,popstate,beforeunload등window event를 활용하여 페이지 전환 등의 이벤트 시 핸들러 등록react-router,reach-router등의 라이브러리를 활용하면, 라우팅 관련 기능을 쉽게 사용할 수 있음.
❏ react-router
declarative: 서술문의(<Link to=”/login”>- JSX),imperative: 반드시 해야하는(handleClick = () ⇒ push(’/login’)- history API)Declarative routing for React- React의
JSX를 이용하거나,History API를 사용하여 라우팅을 구현한다. - 웹에서는
react-router-dom을 사용한다.(react-router-native도 있음) - 적용시, 서버의 모든
path에서 같은 앱을 서빙하도록 해야 한다. React컴포넌트를 특정path와 연결하면, 해당하는path로 진입 시 컴포넌트를 렌더링하게 한다.query,path variable등URL parameter를 얻어 활용한다.- 조건에 맞지 않을 경우
redirect함<Redirect to ="/register" /> - 페이지 이동 시, 이벤트 핸들러를 등록함
history.listen(cb) /posts/my-post-1등의nested route를 구현한다.BrowserRouter로 감싸Router Context를 제공해야 한다.Route로path를 정의하고, 그 안에 렌더링하고자 하는 컴포넌트를 ㅓㄴㅎ음Link로 특정 페이지 이동 시, 리로드 없이 페이지가 이동함Switch로 매칭되는 라우트 하나를 렌더링하게 한다. (exact혹은switch를 쓰지 않으면 모두 렌더링 시킨다.)
// 라우터는 동기적으로 확인한다.
<BrowserRouter>
<Switch>
<Route path="/about"><AboutPage></Route>
<Route path="/contact"><ContactPage></Route>
<Route path="/"><HomePage></Route>
</Switch>
</BrowserRouter>
NavLink의 특징은 매칭 되는path가 자기 자신인 경우 강조 처리해준다.
728x90
❏ BrowserRouter
- 브라우저 환경에서 라우팅 기능을 사용할 수 있는 컴포넌트
HTML5의HistoryAPI를 사용하여,UI와URL의 싱크를 맞추는 역할을 담당한다.- 모든
URL에 대해 동작하게 하기 위해서는 서버 설정 필요 - 모든
path앞의basename을 지정할 수 있다. (basename=”/ko”) forceRefresh로 페이지 이동 시 리프레시할 것인지 지정할 수 있다.
❏ Switch
- 여러
Route중 매치되는Route위에서부터 하나를 선택하여 렌더링한다. - 매칭되는
Route가 없으면 아무것도 보여주지 않음.callback용으로404 Not Found Page를 추가함 path="/"의 경우 모든path에 매칭되므로exact키워드를 추가하거나 가장 아래로 내린다.
❏ Route
path와 컴포넌트를 매칭함- 매칭되는 컴포넌트는
children으로 넣어주거나component prop으로 넘김 exact키워드로 정확하게 매칭하는path를 설정함Route로 렌더링 되는 최상위 컴포넌트는match,location,history를prop으로 받음render prop으로 매칭되었을 때, 실제 어떤 컴포넌트를 렌더링할지 통제함
❏ Redirect
Link와 비슷하나, 렌더링되면to prop으로 지정한path로 이동함Switch안에서 쓰일 경우from ,to를 받아 이동하게 만듬(from =”/” to=”/login”)
// 선언방식(선호)
if (!users) return <Redirect to="/abc" />
return <div>userPage</div>
// 명령방식
if(!users) history.push("/abc")
return <div>userPage</div>
❏ Link, NavLink
to prop을 특정URL로 받아 클릭 시 네비게이션 함anchor tag를 래핑함(a tag)NavLink의 경우, 매칭 시 어떤 스타일을 가질 지 등의 추가 기능이 있음<NavLink to ="/users"></>to에location object나 함수를 받을 수 있다. (hash,pathname,state객체 등...)
❏ useHistory, useLocation, useParams, useRouteMatch
- 원래는 최상위 컴포넌트에서만 접근 가능했으나,
hook을 사용함으로써react-router관련 객체에 접근할 수 있다. history,location,params,match객체에 접근함
❏ react-router 응용
private Route: 특정 조건이 충족되지 않았을 때 다른 페이지로Redirect하도록 하는 기능, 유저의 상세페이지, 개인정보 변경 페이지 등을 만들 때 사용됨.
// declarative(선언적) 방법
function PrivateRoute({ component: Component, ...props }){
return <Route {...props} render={props => {
const isLoggedIn = !!getUserInfo()
if(!isLoggedIn){
return <Redirect to="/login" />
}
return <Component {...props} />
}}
}
// imperative(명령적) 방법
function usePrivateRoute(validateFunc){
const history = useHistory();
useEffectt(() => {
if (!validateFunc()){
history.push("/login")
}
}, [])
}
usePrivateRoute(getUserInfo);반응형
'Frontend > 엘리스 SW 엔지니어 트랙' 카테고리의 다른 글
| [ 엘리스 SW 엔지니어 트랙 ] 56일차(12주차: React III - 상태관리, Redux, 테스팅 기법, jest, react-testing-library ) (0) | 2022.01.11 |
|---|---|
| [ 엘리스 SW 엔지니어 트랙 ] 55일차 (0) | 2022.01.08 |
| [ 엘리스 SW 엔지니어 트랙 ] 53일차 (0) | 2022.01.06 |
| [ 엘리스 SW 엔지니어 트랙 ] 52일차 (0) | 2022.01.05 |
| [ 엘리스 SW 엔지니어 트랙 ] 51일차(11주차: React II - CSS in JS, SPA, API연동) (0) | 2022.01.04 |
댓글