SPA ( Single Page Application ) 이란?
하나의 페이지로 만들어진 애플리케이션을 의미한다.
전통적인 웹 애플리케이션 vs SPA
- SPA는 html 파일을 브라우저 측에서 로드, 필요한 데이터는 API와 Ajax 통신을 이용해 처리한다.
- 브라우저에서 사용자가 상호작용하면 필요한 부분만 업데이트해서 처리
- 멀티플랫폼 Android, IOS에 대응하여 웹뷰로 처리하는 목적으로 사용
SPA의 단점 (CSR 방식)
● 앱의 규모가 커지면, JS 파일도 너무 커져서 로딩이 오래 걸린다.
● 브라우저에서 렌더링이 완료되기 까지 비어있는 화면이 나온다.
● 그래서 규모가 큰 애플리케이션은 SSR(서버사이드렌더링) 방식으로 처리한다. ▶ 웹팩 처리 필요
라우팅이란?
● 브라우저의 주소 상태에 따라 다양한 화면을 보여주도록 처리하는 것을 라우팅이라 한다.
라우팅의 사용이유는 ?
● Create - React - App으로 프로젝트를 생성하게 되면 기본적으로 SPA에 CSR(클라이언트 렌더링) 이다.
● 하나의 페이지만 사용하게 되는 것이다.
● SPA이지만 라우터를 활용해 사용자로 하여금 여러 페이지가 존재하는 것처럼 느끼게 할 수 있다.
라우터 설치하고 프로젝트 시작하기
1. 라우터를 적용할 프로젝트 생성
npm create react-app 프로젝트명
2. 라우터 설치
npm install react-router-dom
3. 프로젝트 시작
npm start
라우터 적용하기
- 라우터를 사용할때는 index.js에서 App 컴포넌트를 <BrowserRouter>로 감싸준다.
- 페이지 컴포넌트 만들기
- App 컴포넌트에서 <Routes>를 사용해서 분기
- 주소요청을 통해 확인
index.js
import { BrowserRouter } from "react-router-dom";
....
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<BrowserRouter>
<App />
</BrowserRouter>
);
App.js
import { Route } from "react-router-dom";
function App() {
return (
<Routes>
<Route path='/' element={<Home/>}/>
// '/'요청은 Home 컴포넌트가 나타난다.
<Route path='/user' element={<User/>}/>
// '/user'요청은 User 컴포넌트가 나타난다.
<Route path='/info' element={<Info/>}/>
// '/info'요청은 Info 컴포넌트가 나타난다.
</Routes>
);
}
export default App;
Link를 이용해서 다른 페이지 이동
- link 태그는 화면에서 a 태그로 생성
- to 속성에는 연결할 요청 주소를 입력한다.
- 어느 컴포넌트든 사용이 가능하다.
//.....return (
<ul>
<li><Link to='/user'>회원페이지</Link></li>
</ul>
)
URL 파라미터 or 쿼리스트링
같은 컴포넌트라도 전달되는 데이터에 따라서 다른 내용을 보여줘야 하는 경우가 있다.
1. 쿼리 스트링
● 쿼리스트링은 주소의 ? 뒤에 키=값의 형태로 넘어가는 매개값이다.
● 별도의 라우터 설정은 하지 않아도 된다.
● 컴포넌트에서는 useLocation() 훅 or useSearchParams() 훅을 사용해서 쿼리스트링을 받을 수 있다.
/ 경로 ? 키 = 값 & 키 = 값
//.....return (
<ul>
<li><Link to='/user?id=aa123&key=1'>회원페이지(쿼리파람)</Link></li>
</ul>
)
※ 어디서 많이 봤다면 일반적으로 get 방식에 데이터 보낼 때 사용하는 걸 생각하면 된다.
컴포넌트에서 사용하는 방법이다.
userLocation() 훅
const location = userLocation();
useSearchParams() 훅
const [객체, function] = useSearchParams()
const [obj, setObj] = useSearchParams();
let id = obj.get("id");//request.getParameter("키")let key = obj.get("key");
- 배열을 반환
- 첫 번째 요소는 쿼리 파라미터를 조회하거나 수정하는 get,set이 담긴 객체
- 두 번째 요소는 쿼리 파라미터를 객체로 업데이트 하는 함수 반환
2. URL 파라미터
● URL 파라미터는 주소 뒤에 /경로/값/값 의 형태로 넘어가는 매개값이다.
● 라우터에 추가적인 설정이 필요하다 ( /주소/:키)
● 컴포넌트에서는 usePaarams() 훅을 사용하여 URL 파라미터를 받을 수 있다.
라우터
function App() {
return (
<Routes>
.....
<Route path='/info/:num' element={<Info/>}/>
</Routes>
);
}
export default App;
링크
//.....return (
<ul>
<li><Link to='/info/1'>1번 info</Link></li>
<li><Link to='/info/2'>2번 info</Link></li>
<li><Link to='/info/3'>3번 info</Link></li>
</ul>
)
컴포넌트
useParams() 훅
let param = useParams();
/param에는 link로 넘어온 키가 담겨있다.
중첩 라우터로 공통 부분 처리하기
- 글페이지가 있고, 글에 따른 상세화면이 있다고 가정
- 라우터의 설정은 아래 처럼 보여진다.
- 아래 설정은 두 라우터가 다르기 때문에 각각 다른 화면이 보인다.
<Routes>
<Route path='/board' element={<Board/>}/>
<Route path='/board/:num' element={<BoardContent/>}/>
</Routes>
- 만약 Board 목록 페이지를 공통으로 사용, 상세페이지를 서브로 보여주도록 처리하려면 중첩라우터를 활용
- 중첩라우터로 적용되면 부모컴포넌트에서 <Outlet> 컴포넌트를 활용해서 하위 라우터를 보여지게 할 수 있다.
<Routes>
<Route path='/board' element={<Board/>}>
<Route path=':num' element={<BoardContent/>}/>
</Route>
</Routes>
Board
const Board = () => {
return (
<div>
<h3>게시글목록</h3>
<ul>
<li><Link to='/board/1' >글1</Link></li>
<li><Link to='/board/2' >글2</Link></li>
<li><Link to='/board/3' >글3</Link></li>
</ul>
{/* Oulet컴포넌트가 사용된 자리에 중첩된 내용이 보여지게됩니다 */}
<Outlet/>
</div>
)
}
export default Board;
BoardContent
const BoardContent = () => {
let {num} = useParams()
return (
<div>
<h3>글 상세페이지</h3>
{num}번 글입니다
</div>
)
}
export default BoardContent;
라우터의 부가적인 기능
- NewLink 컴포넌트
● 링크에서 사용하는 경로가 라우터의 경로와 일치하면 특정스타일을 적용 - useNavigate() 훅 vs Navigate 컴포넌트
useNavigate() 훅
● JS의 history 객체를 대신한다.
● 이벤트에서 사용
Navigate 컴포넌트
● 리다이렉트 기능
● 렌더링시에 사용
NewLink 컴포넌트
- NavLink는 링크의 경로가 라우터의 경로와 일치하면 특정스타일을 적용
- NavLink는 style속성을 제공
- style속성에는 실행시킬 함수를 작성
- 이 함수에 매개변수로 {isActive : boolean}객체를 넣어주는데, 활성화 여부를 표시가 가능
- 사용은 반드시 {isActive}변수로 구조분해할당
const Board = () => {
return (
<div>
<h3>게시글목록</h3>
<ul>
{/*
<li><Link to='/board/1' >글1</Link></li>
<li><Link to='/board/2' >글2</Link></li>
<li><Link to='/board/3' >글3</Link></li>
*/}
<li><NavLink to='/board/1' style={
({isActive}) => {
return isActive ? myStyle : undefined
}
}>글1</NavLink></li>
<li><NavLink to='/board/2' style={({isActive}) => (isActive ? myStyle : undefined )}>글2</NavLink></li>
<li><NavLink to='/board/3' style={({isActive}) => (isActive ? myStyle : undefined )}>글3</NavLink></li>
</ul>
{/* Oulet컴포넌트가 사용된 자리에 중첩된 내용이 보여지게됩니다 */}
<Outlet/>
</div>
)
}
export default Board;
useNavigate() 훅
- useNavigate훅 은 특정 event가 발생할 때, url을 조작할 수 있는 함수를 제공
- react v6 에서 useHistory 가 변화한 것
- JS의 history객체를 대신
import { Fragment } from "react";
import { NavLink, Outlet, useNavigate } from "react-router-dom";
const Header = () => {
//useNavigate() 훅
let nav = useNavigate();
const goHome = () => {
nav('/내가원하는 주소')
}
return (
<button onClick={goHome}>이동</button>
)
}
export default Header;
Navigate 컴포넌트
- <Navigate> 컴포넌트는 렌더링 될 때 현재 위치를 변경 (렌더링 중 만나게 되면, 페이지를 강제로 이동시킴)
- useNavigate()훅과 비슷해보이지만 useNavigate()훅은 렌더링 과정에 사용할 수 없다.
const MyPage = () => {
/*
렌더링 과정에 nav를 쓰지말라는 경고 후 작동이 안됩니다.
let nav = useNavigate()
let loginYN = false;
if(!loginYN) {
nav('/');
}
*/
//Navigate컴포넌트let loginYN = false;
//locaion.href = 경로 와 비슷
if(!loginYN) {
return <Navigate to='/' replace={true}/>
}
return (
<div>
여기는 권한있는 사람만 들어옴
</div>
)
}
export default MyPage;
'Programming > React' 카테고리의 다른 글
[REACT] ContextAPI (0) | 2024.05.14 |
---|---|
[REACT] Ajax로 외부 데이터 통신하기 (0) | 2024.05.14 |
[REACT] React에 CSS 적용하기 (0) | 2024.05.14 |
[REACT] 훅. Hook (2) | 2024.05.14 |
[REACT] 컴포넌트 반복 (0) | 2024.05.14 |