์ด ๊ธ์ ๋ฆฌ์กํธ์ ์ด์ฌ์๋ค์ ์ํ ๊ธ๋ก ๊น์ ๋ด์ฉ์ ์ต๋ํ ๋ฐฐ์ ํ๊ณ ์ฌ์ด ๊ฐ๋ ์ ๋ํด ์์ฑํ์๊ณ , ๋ฆฌ์กํธ์ ์ง์ ์ฅ๋ฒ ์ ๋ฎ์ถ๊ธฐ ์ํ ์์๋ก ์ด๋ ค์ด ๋ด์ฉ์ด ์๋ต๋์ด ์์ ์๋ ์์ต๋๋ค.
์ด ๋ถ๋ถ์ ๊ฝค๋ ํต์ฌ์ ์ด๋ผ๊ณ ์๊ฐํ๊ธฐ ๋๋ฌธ์ 3๋ถ์์ผ๋ก ๋๋ ์ ์ค๋ช ํด๋ณด๋๋ก ํ๊ฒ ๋ค.
ํด๋น ๊ธ์ ๋ํด์ ๋ณธ์ธ์ด ์ด ๋ถ๋ถ์ ๋์ด๊ฐ๋ ๋๊ฒ ๋ค๊ณ ์๊ฐํ๋ ๋ถ๋ถ์ ๋์ด๊ฐ์ ํ์ธํ๋ ๊ฒ์ ๊ถ์ฅํ๋ค. ํ์ง๋ง ๊ธธ์ง ์์ ๊ธ์ด๋ฏ๋ก ๊ฐ๋ณ๊ฒ ์ฝ๋ ๊ฒ๋ ์ข์ ๋ฐฉ๋ฒ์ด๋ค.
- 1๋ถ ๋ฆฌ์กํธ๊ฐ ํ์ด์ง๋ฅผ ๋ผ์ฐํ ํ๋ ๋ฐฉ๋ฒ
- 2๋ถ Broswer History API๋ฅผ ์ฌ์ฉํด์ ํ์ด์ง ๋ผ์ฐํ ํ๊ธฐ
- 3๋ถ react-router-dom์ ์ด์ฉํด์ ํ์ด์ง ๋ผ์ฐํ ํ๊ธฐ
์ฐ๋ฆฌ๋ ์ ๋ฒ ์๊ฐ์ ๋ฆฌ์กํธ๊ฐ ํ์ด์ง์์ ์ด๋ค ์์ผ๋ก ๋ผ์ฐํ ๋๊ธธ ์ํ๋์ง? ์ ๋ํด์ ์ ๊น ์์๋ณด์๋ค.
๊ทธ๋ฆฌ๊ณ SPA๋ฐฉ์์ผ๋ก ํ์ด์ง๋ฅผ ๊ตฌ์ฑํ๋ ๋ฐฉ๋ฒ์ ๋ํด์ ์ ๊น ์คํ์ ํด๋ณด์๋๋ฐ, ์ด๋ฒ ์๊ฐ์๋ ๋ธ๋ผ์ฐ์ ํ์คํ ๋ฆฌ API์ ๋ํด์ ๋ ๊น๊ฒ ์์๋ณด๋ ค๊ณ ํ๋ค.
๋ธ๋ผ์ฐ์ ํ์คํ ๋ฆฌ API์ ๋ํด์๋ ๋ ์์ธํ ์๊ณ ์ถ์ ์ฌ๋์ MDN Docs์์ ํ์ธํด๋ณด๋ ๊ฒ๋ ์ข์ ๋ฐฉ๋ฒ์ด๋ค.
๋ธ๋ผ์ฐ์ ํ์คํ ๋ฆฌ API
SPA๋ฅผ ๊ตฌ์ฑํ๋ ค๋ฉด ์ค์ํ ๊ฐ๋ ์ด ์๋ค.
- ์๋ฒ๋ก์ ์์ฒญ์ด ์์ด ํ์ด์ง ์ ํ๊ณผ ๋ค๋ก๊ฐ๊ธฐ๊ฐ ๊ฐ๋ฅํด์ผ ํ๋ค.
์ด๋ฐ ๊ฐ๋ ์ ์ ์ฉํ๊ธฐ ์ํด์ ๊ฐ๋จํ๊ฒ History Api์ ๋ํด์ ์์์ผ ํ๋๋ฐ ๋ชจ๋ ๊ฒ์ ๋ค ์ ํ์๋ ์๋ค. ๋ฑ 3๊ฐ์ง๋ง ์์๋ณด์.
- pushstate
- replacestate
- popstate
pushstate() ํจ์
pushstate()
ํจ์๋ ๋ค์๊ณผ ๊ฐ์ ๊ตฌ์กฐ๋ฅผ ๊ฐ๋๋ค
pushstate(state, title, url)
์ด๋ ๋ธ๋ผ์ฐ์ ๊ฐ ์ธ์ ์คํ์ดํธ๋ฅผ ์คํ์ ์ถ๊ฐํ๋ค๊ณ ํ๋๋ฐ, ์ฝ๊ฒ ์ค๋ช ํ์๋ฉด ํด๋น url๋ก ์ด๋ํ ์ ์๊ฒ ํด์ฃผ๋ ์ญํ ์ ํ๋ค.
์๋ฒ์ ์์ฒญ ์์ด
replacestate() ํจ์
replacestate()
ํจ์๋ ๋ค์๊ณผ ๊ฐ์ ๊ตฌ์กฐ๋ฅผ ๊ฐ๋๋ค.
replacestate(state, title, url)
์ด๋ ๋ธ๋ผ์ฐ์ ๊ฐ ํ์ฌ ํ์คํ ๋ฆฌ๋ฅผ ํด๋น url๋ก ์ ์ฅํ๊ณ ์ง์ ์ด๋ํ ์ ์๊ฒ ํ๋ค.
์๋ฒ์ ์์ฒญ ์์ด
popstate() ํจ์
popstate()
ํจ์๋ ๋น ๋ฅธ ์ค๋ช
์ ์ํด MDN์ ๋ฌธ์ ์ผ๋ถ๋ฅผ ์บก์ณํ์๋ค.
์ด์ ๋ณธ๊ฒฉ์ ์ผ๋ก ํ์ด์ง๋ฅผ ๊ตฌ์ฑํด๋ณด์.
React์ Broswer Histroy APi๋ก SPA ๊ตฌ์ฑํ๊ธฐ
๋ธ๋ผ์ฐ์ ํ์คํ ๋ฆฌ๋ ์ง๋ ์๊ฐ์๋ ์ ๊น ํ์ง๋ง ์ด๋ฒ์๋ ์กฐ๊ธ ๋ ๋ค์ํ ์ปจํ ์ธ ๋ฅผ ์ถ๊ฐ์์ผ์ ๊ตฌ์ฑํด๋ณด์.
๊ฒฐ๊ณผ์ ์ผ๋ก๋ ์ฐ๋ฆฐ ์ด๋ฐ ํ์ด์ง๋ฅผ ๋ง๋ค ๊ฒ์ด๋ค.
ํ์ด์ง ํ์ localhost:3000 ์ด๊ณ ๊ฐ๊ฐ์ ๋ฒํผ์ ํด๋ฆญํ๋ฉด ๋ค์๊ณผ ๊ฐ์ ํ๋ฉด์ด ๋ฑ์ฅํ ๊ฒ์ด๋ค.
๋ญํน์ ํด๋ฆญํ๋ฉด ์ฌ์ฉ์ ๋ญํน์ด ๋์ค๊ณ ์ฌ์ฉ์๋ฅผ ํด๋ฆญํ๋ฉด ์ฌ์ฉ์ ์ ๋ณด๊ฐ ๋์ค๊ฒ ํ ๊ฒ์ด๋ค. ์ด๋ป๊ฒ? ์๋ฒ์ ์์ฒญ ์์ด
์์ค ์ฝ๋
import React, { Component } from 'react';
import './App.css';
class App extends Component {
state = {
pageName : '', // ํ์ฌ ํ์ด์ง๋ฅผ ์ํ ๊ฐ์ผ๋ก ๊ด๋ฆฌ
};
componentDidMount(){
window.onpopstate = event => { // popstate ๊ฐ ๋ฐ์ํ๋ฉด ํ์ด์ง๋ฅผ ์ ํ
this.onChangePage(event.state);
}
}
onChangePage = pageName => { // ๋ฒํผ์ด ํด๋ฆญ๋๋ฉด pageName์ด๋ผ๋ ์ํ๊ฐ์ ๋ฐ๊ฟ์ฃผ๊ธฐ ์ํ ๋ฉ์๋
this.setState({ pageName });
};
onLankingClick = () => { // ๋ญํน ํ์ด์ง ๋ฒํผ ํด๋ฆญ
const pageName = 'lanking';
window.history.pushState(pageName, '', '/lanking');
this.onChangePage(pageName);
}
onUserClick = () => { // ์ฌ์ฉ์ ํ์ด์ง ๋ฒํผ ํด๋ฆญ
const pageName = 'user';
window.history.pushState(pageName, '', '/user');
this.onChangePage(pageName);
}
render() {
const { pageName } = this.state;
return (
<div>
<button className="lanking" onClick={this.onLankingClick}>Lanking</button>
<button className="user" onClick={this.onUserClick}>User</button>
{!pageName && <Home />}
{pageName === 'lanking' && <Lanking />}
{pageName === 'user' && <User />}
</div>
);
}
}
function Home() {
return <h2>๋ฉ์ธ ํ์ด์ง ์
๋๋ค. ๋ฒํผ์ ํด๋ฆญํ์ธ์</h2>;
}
function Lanking(){
return (
<div>
<h2>๋ญํน ํ์ด์ง ์
๋๋ค.</h2>
<br></br>
<h4>๊ฒฝํ์น ๋ญํน</h4>
<br></br>
<ol>
<li>์ฌ์ฉ์ 3 : 44012</li>
<li>์ฌ์ฉ์ 1 : 42019</li>
<li>์ฌ์ฉ์ 5 : 20919</li>
<li>์ฌ์ฉ์ 4 : 9918</li>
</ol>
</div>
);
}
function User() {
return (
<div>
<h2>์ฌ์ฉ์ ์ ๋ณด ํ์ด์ง ์
๋๋ค.</h2><br></br>
<div>
<h4>์ฌ์ฉ์ 1</h4><br></br>
์ฌ์ฉ์ 1 ์
๋๋ค.
</div>
<div>
<h4>์ฌ์ฉ์ 2</h4><br></br>
์ฌ์ฉ์ 2 ์
๋๋ค.
</div>
<div>
<h4>์ฌ์ฉ์ 3</h4><br></br>
์ฌ์ฉ์ 3 ์
๋๋ค.
</div>
</div>
);
}
export default App;
๋จ์
์ด๋ฐ ์์ผ๋ก ํ์คํ ๋ฆฌ API๋ฅผ ์ฌ์ฉํ ์ ์๋๋ฐ, ์ ๊ฒฝ์จ์ผํ ๋ถ๋ถ์ด ๋๋ฌด๋๋ ๋ง์์ง๋ค.
๋จ๋ ์ ์ผ๋ก ์ํ๋๋ ๊ฒ์ด ์๋๋ผ ๋ธ๋ผ์ฐ์ ์ API์ ์ํด์ ๊ด๋ฆฌ๋๋ฏ๋ก ๊ฐ๊ฐ์ ๋ธ๋ผ์ฐ์ ๋ง๋ค ์คํ ๊ฒฐ๊ณผ๊ฐ ๋ค๋ฅผ ์๋ ์๋ ๊ฒ์ด๊ณ , ๋ ๊ทธ์ ๋ฐ๋ฅธ ๊ฒฐ๊ณผ ์ถ๋ ฅ๋ ๊ฐ๊ฐ์ผ๋ก ํด์ฃผ์ด์ผ ํ ๊ฒ์ด๋ค.
์ด๋ฐ ๊ฒ์ ์กฐ๊ธ ์์ ๊ณ ์ ์ฐ๋ฆฌ๋ ๋ค์ ์๊ฐ์ react-router-dom
์ ์ด์ฉํด์ ์กฐ๊ธ ๋ ์์ ์ ์ผ๋ก ๊ตฌํํด๋ณผ ๊ฒ์ด๋ค.
๋๊ธ