React SPA
학습 목표
* SPA(Single-Page Application)의 개념
* SPA의 장, 단점
* 와이어프레임을 보고 컴포넌트 구분하기
SPA(Single-Page Application)
SPA의 등장 배경, 개념, 장단점
SPA의 등장 배경과 개념
전통적인 웹사이트에서는 사용자가 웹사이트 내 다른 페이지 이동시 브라우저가 매번 “페이지 전체”를 불러옴
→ 페이지 전체를 불러오는 행위: 깜빡인다
→ 중복되는 요소들도 매번 로딩해서 불필요한 트래픽 발생시키고 느리게 함
→ 웹사이트가 복잡해지고 애플리케이션 형태로 되며 사용자와 서비스 사이의 상호작용이 증가하며 이 방식의 한계점
SPA의 경우 Menu, Footer와 같이 페이지 전환 후 중복되는 부분은 새로 로딩하지 않는다
→ 업데이트가 필요한 부분(데이터)만 새로 불러온다
→ 2000년대 중반부터 이러한 개발 방식을 이용한 웹 애플리케이션이 보편화됨(SPA)
정리하면 SPA란 서버로부터 완전히 새로운 페이지를 불러오는 것이 아니라, 화면을 업데이트하기 위해 필요한 데이터만 서버에서 전달 받아 브라우저에서 해당하는 부분만 업데이트하는 방식으로 작동하는 웹 애플리케이션이나 웹 사이트
SPA의 장점
* 사용자와의 빠른 상호작용:
전체 페이지가 아니라 필요한 부분의 데이터만 받아 화면에 업데이트하므로
* 서버 과부하 감소:
서버에는 요청받은 데이터만 넘겨주면 되기 때문에 과부하 문제가 감소
* 더 나은 사용자 경험:
전체 페이지를 새로 렌더링할 필요가 없기 때문
SPA방식 서비스의 대표적인 예: 유튜브, facebook, Gmail, 넷플릭스 등 많은 서비스 등
SPA의 단점
* 긴 첫 화면 로딩 시간:
SPA의 경우 JavaScript 파일의 크기가 큰데, 이 때문에 이 JavaScript 파일을 기다리는 시간으로 인해 첫 로딩 시간이 김
브라우저는 첫 화면 로딩 시 HTML 파일을 읽고 그 안에 script tag의 JavaScript 파일을 다시 받아오는 과정을 거침.
→ SPA의 경우 html 파일은 거의 비어 있고 대부분의 코드가 JavaScript 파일에 들어 있다
이를 기다리는 시간 때문에 첫 로딩이 길어짐
* 검색 엔진 최적화가 좋지 않음:
검색 엔진 최적화란 구글, 네이버 같은 검색 엔진이 자료를 수집하기 좋도록 웹 페이지를 구성하는 것
검색 엔진은 자료 수집 시 HTML 파일에 있는 자료를 분석하는 방식으로 동작함
→ SPA는 html 파일이 거의 비어 있기 때문에 검색 엔진이 적절히 동작 못함
→ SPA에서도 검색 엔진 최적화에 대응할 수 있도록 검색 엔진이 발전하고 있어서 단점이 사라지는 추세
Wireframe
컴포넌트를 어떻게 나눌지 고민하는 과정
→ 어떤 컴포넌트를 생성하고 어떻게 조합 할지에 대한 구상
유튜브 만들기의 예
화면 상단
검색 창을 구현
상단 전체에 <Header />
그 자식 컴포넌트 <Search /> 와 <Setting />
<Header />
는 애플리케이션 내의 어떤 페이지에 가더라도 늘 상단에 위치
→ 모든 페이지마다 따로 만들 것이 아니라 한번만 만들어서 모든 페이지에서 사용할 수 있도록 로직 구상
화면 중앙
영상 리스트가 나오는 곳
<ContentList /> // 크리에이터들이 올린 영상들을 담고 있음
<Content /> // 각 영상들의 정보
컨텐츠 리스트 안에 컨텐츠 컴포넌트가 들어가 있는 구조인데, 동일한 형태를 가진 영상물들이 반복적인 형태로 화면을 구성
→ <Content />
를 한번만 만들어서 재사용
→ 나열되는 영상 정보들은 디테일은 달라도 기능과 layout이 동일하기 때문
이게 끝?
가장 작은 단위의 컴포넌트인
썸네일, Description, Channel name, Date, Views , …
→ 이렇게 애플리케이션 안에서 다뤄지는 데이터를 컴포넌트끼리 유기적으로 주고 받을 수 있도록 설계가 필요
React Router
학습 목표
* React Router DOM 설치: npm install react-router-dom
* React Router DOM을 이용한 SPA 구현
* 라우팅 구조 구현 및 이에 필요한 기초 문법
React Router
React Router를 이용한 React SPA 개발
SPA 와 Routing
SPA는 하나의 페이지를 가지고 있지만 사실 한 종류의 화면만 사용하진 않는다
→ 예를 들어 Twittler 같은 SPA 생성 시를 생각
메인 트윗 모음 페이지
알림 페이지
마이 트윗 페이지 등
이와 같은 다른 페이지들도 필요
→ 이 화면에 따라 주소도 달라진다
라우팅(Routing) : 이렇게 다른 주소에 따라 다른 뷰를 보여주는 과정을 말함. “경로에 따라 변경한다” 는 의미
→ React 자체에는 이 기능이 내장되어 있지 않으므로 React Router 라이브러리 사용
React Router 주요 컴포넌트
주요 컴포넌트는 크게 3가지로 나눈다
* router(라우터 역할): <BrowserRouter />
* route matchers(경로를 매칭): <Switch />, <Route />
* route changer(경로를 변경): <Link />
이 컴포넌트들을 사용하기 위해서는 명령어로 React Router 라이브러리에서 불러와야 함
import { BrowserRouter, Switch, Route, Link } from “react-router-dom”
React Router 사용 환경 세팅
1.react-router 라이브러리 설치
// 특정 폴더명(simpleroute)으로 React App 설치
> npx create-react-app simpleroute
> cd simpleroute
// react-router 라이브러리 설치
> npm install react-router-dom
2.App.js로 react-router 컴포넌트 꺼내오기(import)
컴포넌트를 꺼내오기 위한 import 구문 작성
import React from “react”;
import { BrowserRouter, Switch, Route, Link } from “react-router-dom”; //react-router 컴포넌트를 import 해주는 구문을 추가
export default function App)(){
return (...)
}
React Router Hands-on 실습
React 웹 애플리케이션 목업을 통한 실습
<최소 조건>
* React Router DOM 의 주요 컴포넌트들을 이용해 주소에 따른 3가지 뷰(Home, MyPage, Dashboard) 제공
- Home 페이지의 주소 “/”
- MyPage 페이지의 주소 “/mypage”
- Dashboard 페이지의 주소 “/dashboard”
Route 준비
App.js 하단에 아래 코드 작성
// Home 컴포넌트
function Home() {
return <h1>Home</h1>;
}
// MyPage 컴포넌트
function MyPage() {
return <h1>MyPage</h1>;
}
// Dashboard 컴포넌트
function Dashboard() {
return <h1>Dashboard</h1>;
}
메뉴 만들기
메뉴 제작을 위해 <ul>
, <li>
태그를 사용
function App () {
return (
<div>
<nav>
<ul>
<li>
Home
</li>
<li>
MyPage
</li>
<li>
Dashboard
</li>
</ul>
</nav>
</div>
)
}
export default App;
주소에 따라 페이지 뷰 다르게 만들기
BrowserRouter
웹 애플리케이션에서 HTML5의 History API를 사용해 페이지를 새로고침하지 않고도 주소를 변경할 수 있게 함. ReactDOM의 렌더 단계인 index.js에 넣어서 활용할 수 도 있다.
BrowserRouter가 상위에 작성되어 있어야 Route 컴포넌트를 사용할 수 있다
Switch, Route
경로를 매칭 해 주는 역할을 하는 컴포넌트
`<Switch>`: 여러 `<Route>`를 감싸서 그 중 경로가 일치하는 단 하나의 라우터만 렌더링 시켜주는 역할. `<Switch>`를 사용하지 않으면 매칭되는 모든 요소를 렌더링함
`<Route>`: path 속성을 지정하여 해당 path에 어떤 컴포넌트를 보여줄지를 정함. Link 컴포넌트가 정해주는 URL 경로와 일치하는 경우에만 작동
Link
경로를 연결 해 주는 역할을 하는 컴포넌트.
페이지 전환을 통해 페이지를 새로 불러오지 않고 애플리케이션을 그대로 유지하여 HTML5 History API를 이용해 페이지의 주소만 변경해 줌
→ ReactDOM으로 렌더를 시키면 <Link>
컴포넌트는 <a>
태그로 바뀌는 모습을 볼 수 있다
React Router 에서 <a>
태그가 아닌 <Link>
를 사용하는 이유가 있나요?
<a>
태그는 페이지를 전환하는 과정에서 페이지를 불러오기 때문에 다시 처음부터 렌더링을 시킵니다. 즉, 새로고침 현상이 일어나게 되죠. 하지만<Link>
컴포넌트는 페이지 전환을 방지하는 기능이 내장되어있기 때문에 SPA를 구현할 수 있습니다.
본격적인 코드 구성 진행
1.<BrowserRouter>
로 <Route>
컴포넌트를 이용하기 위한 환경을 세팅
2.<Switch>
와 <Route>
로 주소 경로와 아까 만든 3개의 컴포넌트를 연결해 준다
- Home 컴포넌트 Route 에만 존재하는 exact 라는 것을 보았습니다, 언제 쓰는건가요?
React router의 특성상 exact속성이 없으면 해당 경로(예시의 "/")로 시작하는 중복된
<Route>
컴포넌트를 모두 보여줍니다. exact는 주어진 경로와 정확히 일치해야만 설정한<Route>
컴포넌트를 보여주는 역할을 합니다.
- exact 속성을 쓰지 않고도 페이지가 전환되는 것을 봤습니다. 왜 그런건가요?
<Switch>
를 사용하여 exact 역할을 대신 해주는 경우입니다. 하지만<Switch>
는 순서와 위치가 중요합니다. 위에서 아래로 경로를 하나씩 검사하면서 해당 경로에 해당하는 라우트를 실행시키기 때문입니다. 이런 경우, 비교할 라우트를 더 상단에 작성해야 합니다. 하지만 만약 위의 예제처럼 Home을 위에 둔 상태에서 exact없이 활용한다면 어떻게 될까요? 중복되는 경로로 인해 다른 라우트로의 이동이 불가능한 것을 확인하실 수 있습니다. 이를 해결하는 방법으로 exact를 사용할 수 있습니다.
3.<Link>
의 to 속성을 활용하여 Route 컴포넌트에 설정해준 path 주소를 연결
전체 작성한 코드를 통해 확인 후 npm run start로 정상 구동 확인해보기
function App() {
return (
<BrowserRouter>
<div>
<nav>
<ul>
<li>
<Link to="/">Home</Link>{/* Link 컴포넌트를 이용하여 경로를 연결합니다 */}
</li>
<li>
<Link to="/about">MyPage</Link>
</li>
<li>
<Link to="/dashboard">Dashboard</Link>
</li>
</ul>
</nav>
<Switch>
<Route exact path="/">
<Home />
</Route>
<Route path="/about">
<MyPage />
</Route>
<Route path="/dashboard">
<Dashboard />
</Route>
</Switch>
</div>
</BrowserRouter>
);
}
function Home() {
return <h1>Home</h1>;
}
function MyPage() {
return <h1>MyPage</h1>;
}
function Dashboard() {
return <h1>Dashboard</h1>;
}
export default App;
React Twittler SPA
Advanced Challenge
App.js에 있는
<BrowserRouter>
를 index.js 로 옮겨보세요. 그리고 Router라는 이름을 붙여보세요.앞서 설명한 것처럼 위 컴포넌트를 index.js에서 활용할 수 있다고 했습니다. 그리고 as를 이용해서 별칭을 붙일 수 있습니다.
import { BrowserRouter as Router} from 'react-router-dom';
ReactDOM.render(<Router><App/></Router>, document.querySelector('#root'));
history 구현하기?
history 메소드를 작성한 파일에서 withRouter를 입혀줘야 한다!
ex) history 작성한 파일 내에서
import { withRouter } from "react-router";
…
export default withRouter(HistoryTest);
react-router-dom의 withRouter 컴포넌트를 사용하여 export로 내보내는 부분의 함수 명을 ()로 감싸준 뒤, 화살표 함수의 인자를 넣는 부분에 props를 넣으시면 props 객체로 history가 들어감을 확인을 할 수가 있습니다.
내가 history를 사용하고자 하는 컴포넌트만 withRouter로 감싸주시고 인자로 props를 주시면 충분히 컴포넌트 내에서 사용 가능합니다.
만일 의도했던 대로 동작이 되지 않으면 기동하고 있던 앱을 한 번 종료를 했다가 다시 기동을 해서 확인을 해주세요.
혹은 현재 내가 위치하고 있는 주소를 확인 해주시면 됩니다. (컴포넌트는 다 주소와 연결이 되어 있습니다)
zoom 강의 내용 정리
react-router 패키지는 선택 패키지이므로 기본적으로 내장되어 있지 않다
→ npm install react-router-dom 으로 설치해야 함
route는 주소를 지정 해주는 것이고
link는 지정된 주소로 가게 해주는 역할
import를 해서 가져올 땐 내보내는 쪽에서는 맨 하단에
export default 내보내는파일명 //으로 써줘야함
TODO : dummyTweets중 kimcoding 이 작성한 트윗 메세지만 있어야 합니다. 을 작성할때
<li className="tweet" id={filteredTweets[0].id}>
// 나중에 키로 쓴다면 key값을 지정을 반드시 해줘야 한다
<Switch>
의 위치는 <Route>
를 감싸는 구조로 위치하면 된다
import { Link } from 'react-router-dom';
// react-router-dom 패키지 안에는 메소드가 많이 있는데 이중에서 Link 하나만 가져올 때는
{}를 이용해 구조 분해 해서 특정 메소드만 가져오는 것이다
import Footer from "../Footer";
// 여기서는 Footer 안에 Footer 메소드 하나밖에 없으므로 이렇게 써도 된다
'SE Bootcamp 내용 정리' 카테고리의 다른 글
SECTION 1 회고 (0) | 2021.09.30 |
---|---|
React - 기초 - 3 (0) | 2021.09.17 |
React – 기초 (0) | 2021.09.15 |
js/node – 고차 함수 (0) | 2021.09.15 |
js/browser - DOM -2 (0) | 2021.09.13 |