π index.html
public ν΄λμ μλ€. λ©μΈ νλ‘κ·Έλ¨μΈ index.jsμ λμλλ κ²μΌλ‘, HTML ν νλ¦Ώ νμΌμ΄λ€. μ΄ νμΌμ΄ μ§μ νμλλ κ²μ μλκ³ , index.jsμ μν΄ μΌμ΄ μμ λ λλ§λ κ²°κ³Όκ° νμλλ€. μ μΌν html μ΄λ€.
π index.js
src ν΄λμ ν¬ν¨λμ΄ μλ€. λ©μΈ νλ‘κ·Έλ¨μ΄λΌκ³ ν μ μλ€. μ¬κΈ°μμ HTML ν νλ¦Ώ λ° JavaScriptμ μ»΄ν¬λνΈλ₯Ό μ‘°ν©νμ¬ λ λλ§νκ³ μ€μ νμνλ€.
π App.js
src ν΄λμ μλ€. μ΄κ²μ μ»΄ν¬λνΈλ₯Ό μ μνλ νλ‘κ·Έλ¨μ΄λ€. μ€μ λ‘ νλ©΄μ νμλλ λ΄μ© λ±μ μ¬κΈ°μμ μ μλλ€.
SPA?
Single Page Application (μ±κΈ νμ΄μ§ μ΄ν리μΌμ΄μ ) μ μ½μ. μ°λ¦¬λ μΈμ€νκ·Έλ¨μ ν΄λ‘ νλ©΄μ λ‘κ·ΈμΈ νμ΄μ§μμ νλμ νμ΄μ§, κ·Έλ¦¬κ³ λ©μΈ νμ΄μ§μμ λ νλμ νμ΄μ§κ° μ‘΄μ¬νλ€. νμ§λ§ 리μ‘νΈμλ htmlμ΄ λ¨ νλλ§ μ‘΄μ¬νκ³ , κ·Έ νλμ νμ΄μ§μ λ‘κ·ΈμΈ κ³Ό λ©μΈ λ νμ΄μ§λ₯Ό 보μ¬μ€μΌ νλ€. μ€μ λ‘ μ°λ¦¬κ° νν 보λ μΉμ¬μ΄νΈλ€ λν νλμ νμ΄μ§μ μ¬λ¬κ°μ§λ₯Ό 보μ¬μ£Όκ³ μλ€.
κ·Έλμ νμν κ²μ΄ react-router μ΄λ€.
λΌμ°ν (Routing)μ΄λ λ€λ₯Έ κ²½λ‘(url μ£Όμ)μ λ°λΌ λ€λ₯Έ View(νλ©΄)λ₯Ό 보μ¬μ£Όλ κ²μ΄λ€. μ¦, νκ°μ μΉνμ΄μ§ μμμ μ¬λ¬ κ°μ νμ΄μ§λ₯Ό 보μ¬μ£Όλ κ²μ΄λ€. 리μ‘νΈ μ체μλ μ΄λ° κΈ°λ₯μ΄ λ΄μ₯λμ΄ μμ§ μλ€. κ·Έλμ 리μ‘νΈκ° νλ μμν¬κ° μλλΌ λΌμ΄λΈλ¬λ¦¬λ‘ λΆλ₯λλ μ΄μ μ€ νλλ€. (νλ μμν¬λ λ΄μ₯λμ΄μλ κΈ°λ₯μ΄ λ§μμ νλ μμν¬κ° κ°λ°μλ₯Ό μ μ΄νλ©°, κ°λ°μλ νλ μμν¬ λ΄μμ μμ§μ¬μΌ νλ€. κ·Έλ¬λ λΌμ΄λΈλ¬λ¦¬λ νλ μμν¬ λ°μμ μμ§μΌ μ μμΌλ©° μ μ΄μ μ£Όμ²΄κ° κ°λ°μλ€. )
μ¬κΈ°μ μ κΉ, react-router λ μ¨λνν° λΌμ΄λΈλ¬λ¦¬μ΄λ€. μ¨λνν° λΌμ΄λΈλ¬λ¦¬? κ°μΈ κ°λ°μλ νλ‘μ νΈ ν, νΉμ μ 체λ±μμ κ°λ°νλ λΌμ΄λΈλ¬λ¦¬μ΄λ©° μ¦ μ 3μ λΌμ΄λΈλ¬λ¦¬λ₯Ό λ»νλ€. μ μμ¬μμ λ§λ κ²μ΄ μλλΌ λ€λ₯Έ μ 체μμ λ§λ ν΄λΉ ν΄ μ§μ λΌμ΄λΈλ¬λ¦¬λ₯Ό κ°λ¦¬ν¨λ€. μ μ‘°μ¬μ μ¬μ©μ μ΄μΈμ μΈλΆμ μμ°μλ₯Ό λ§νλ€.
react-router μ€μΉ
npm install react-router-dom --save
Routes μ»΄ν¬λνΈ κ΅¬ννκΈ°
src ν΄λμ Routes.js νμΌμ λ§λ€μ΄μ€λ€.import React from 'react'; import { BrowserRouter as Router, Switch, Route, } from 'react-router-dom'; import Login from './pages/Login/Login'; import Signup from './pages/Signup/Signup'; import Main from './pages/Main/Main'; class Routes extends React.Component { render() { return ( <Router> <Switch> <Route exact path="/" component={Login} /> <Route exact path="/signup" component={Signup}/> <Route exact path="/main" component={Main} /> </Switch> </Router> ) } } export default Routes;
λλ λ‘κ·ΈμΈκ³Ό λ©μΈνμ΄μ§μ μ κ·Όνλ€. μ¬κΈ°μ 16λ²μ§Έ, 17λ²μ§Έ λΌμΈμexact
μ μ€μμ±: νλμ νμ΄μ§ μμμ μ°λ¦¬λ μ£Όμμ°½μ λ‘κ·ΈμΈκ³Ό λ©μΈ κ²½λ‘μ κ°κ° μ κ·Όν΄μΌνλ€. μ΄ λexact
λ₯Ό μ¨μ£Όμ§ μμΌλ©΄ μ»΄ν¨ν°λ λ‘κ·ΈμΈ νμ΄μ§ μ£Όμ "/" μ λ©μΈ νμ΄μ§ μ£Όμ "/main"μ μ λλ‘ κ΅¬λΆνμ§ λͺ»νκ³ νμ΄μ§κ° λ°λμ§ μλλ€. κ·Έ μ΄μ λ "/main" μ£Όμ μμ κ°μ μ¬λμκ° μ‘΄μ¬νκΈ° λλ¬Έμ μ¬λμλ§ λ³΄κ³ κ°μ μ£ΌμλΌκ³ μκ°νκΈ° λλ¬Έ. κΌexact
λ₯Ό μ¨μ£Όλλ‘ νμ.κ·Έλ¦¬κ³ λ νλ, μλ¨μ importμ μ°μ¬μ§ μμλλ‘ return μμμ κ°μ μμλλ‘ μ°μμμ νμΈν μ μλ€. κ°λ μ±μ μν΄μ μ°μ¬μ§ μμλλ‘ μ¬μ©λμ΄μ§λ μμλλ‘ μ°λλ‘ νμ.
import? : κ°μ Έμ€κΈ°
"κ°μ Έμ€κΈ°"λ λ€λ₯Έ μμ©νλ‘κ·Έλ¨μ μν΄ μμ°λ λ°μ΄ν°λ₯Ό μ¬μ©νλ κ². μΈλΆ λ°μ΄ν°λ₯Ό κ°μ Έμμ μ¬μ©νλ κ²μ΄λ€.
export? : λ΄λ³΄λ΄κΈ°
ν μμ©νλ‘κ·Έλ¨μ©μΌλ‘ μμ±λ λ°μ΄ν°λ₯Ό λ€λ₯Έ νλ‘κ·Έλ¨μμ μ¬μ©ν μ μλλ‘ νμΌ νμμ λ°κΎΈμ΄ μ μ₯νλ κ²μ μλ―Ένλ€. export λ¬Έμ JavaScript λͺ¨λμμ ν¨μ, κ°μ²΄, μμ κ°μ λ΄λ³΄λΌ λ μ¬μ©νλ€. λ΄λ³΄λΈ κ°μ λ€λ₯Έ νλ‘κ·Έλ¨μμ import λ¬ΈμΌλ‘ κ°μ Έκ° μ¬μ©ν μ μλ€.
index.js
ReactDOM.render(<Routes />, document.getElementById('root'));
- νμ¬ νλ©΄μλ
<App />
μ»΄ν¬λνΈκ° 보μ¬μ§κ³ μμ΅λλ€. (λλ Login μ»΄ν¬λνΈ, Main μ»΄ν¬λνΈ)- CRAλ‘ λ§λ μ±μ routing κΈ°λ₯μ μ μ©νλ €λ©΄
index.js
λ₯Ό μμ ν΄μΌ ν©λλ€.<App />
μ»΄ν¬λνΈ λμ μ routingμ μ€μ ν μ»΄ν¬λνΈ(<Routes />
)λ‘ λ³κ²½ν΄μΌ ν©λλ€.
Route μ΄λνκΈ°
Route μ΄λνλ λ°©λ²μ λ κ°μ§
- μ»΄ν¬λνΈ μ¬μ©νλ λ°©λ²
- withRouterHOC λ‘ κ΅¬ννλ λ°©λ² μ»΄ν¬λνΈ μ¬μ©νλ λ°©λ²
import React from 'react'; import { Link } from 'react-router-dom'; class Login extends React.Component { render() { return ( <div> <Link to="/signup">νμκ°μ </Link> </div> ) } } export default Login;
μλ₯Ό λ€μ΄, μ°λ¦¬λ Login.jsμ html μ½λ μμ λ‘κ·ΈμΈ λ²νΌμ λ§ν¬λ₯Ό κ±Έμ΄λμΌλ©΄ λλ€. λ‘κ·ΈμΈ λ²νΌμ ν΅ν΄μ λ©μΈ νμ΄μ§λ‘ μ νλ μ μλλ‘.
Routes.js
μμ μ€μ ν pathλ‘ μ΄λνλ 첫 λ²μ§Έ λ°©λ²μ<Link>
μ»΄ν¬λνΈλ₯Ό μ¬μ©νλ λ°©λ²μ λλ€.react-router-dom
μμ μ 곡νλ<Link>
μ»΄ν¬λνΈλ DOMμμ<a>
λ‘ λ³ν(Compile) λ©λλ€.- cf) JSX - Babel - JavaScript
<a>
νκ·Έμ λ§μ°¬κ°μ§λ‘<Link>
νκ·Έλ μ§μ ν κ²½λ‘λ‘ λ°λ‘ μ΄λμμΌμ£Όλ κΈ°λ₯μ ν©λλ€.- cf)
<a>
vs.<Link>
<a>
- μΈλΆ μ¬μ΄νΈλ‘ μ΄λνλ κ²½μ°<Link>
- νλ‘μ νΈ λ΄μμ νμ΄μ§ μ ννλ κ²½μ°
withRouterHOC λ‘ κ΅¬ννλ λ°©λ²
import React from 'react'; import { withRouter } from 'react-router-dom'; class Login extends React.Component { goToMain = () => { this.props.history.push('/main'); } ** // μ€μ νμ© μμ // goToMain = () => { // if(response.message === "valid user"){ // this.props.history.push('/main'); // } else { // alert("λ μ°λ¦¬ νμ μλ. κ°μ λ¨Όμ ν΄μ£ΌμΈμ") // this.props.history.push('/signup'); // } // } render() { return ( <div> <button className="loginBtn" onClick={this.goToMain} λ‘κ·ΈμΈ </button> </div> ) } } export default withRouter(Login);
<Link />
λ₯Ό μ¬μ©νμ§ μκ³ μμμ onClick μ΄λ²€νΈλ₯Ό ν΅ν΄ νμ΄μ§λ₯Ό μ΄λνλ λ°©λ²λ μμ΅λλ€.goToMain
λΌλ event handlerμμ ꡬνν κ²μ²λΌ props κ°μ²΄μ history (this.props.history
) μ μ κ·Όν΄μ μ΄λν μ μμ΅λλ€.console.log
λ‘this.props.history
μ μ΄λ€ μ 보λ€μ΄ λ΄κ²¨ μλμ§ ν λ² νμΈ ν΄λ³΄μΈμ :)- λ°μ
history
μpush
λ©μλμ μΈμλ‘Routes.js
μμ μ€μ ν pathλ₯Ό λ겨주면, ν΄λΉ λΌμ°νΈλ‘ μ΄λν μ μμ΅λλ€.- μ΄ μ»΄ν¬λνΈ(Login μ»΄ν¬λνΈ)μμ propsμ route μ 보(
history
)λ₯Ό λ°μΌλ €λ©΄ exportνλ μ»΄ν¬λνΈμΒwithRouter
λ‘ κ°μΈμ£Όμ΄μΌ ν©λλ€.- μ΄λ κ²
withRouter
μ κ°μ΄ ν΄λΉ μ»΄ν¬λνΈλ₯Ό κ°μΈμ£Όλ κ²μΒ Higher Order Component (μ΄ν HOC)Β λΌκ³ ν©λλ€.
goToMain ν¨μμμ λ΄μ£ΌμΈμ©
μλ html μ½λμμ λ²νΌ λΆλΆμ 보면 onClick λ©μλμ μμμ μ μν ν¨μλ₯Ό μ§μ ν΄μ€ κ²μ νμΈν μ μλ€.
export default withRouter(Login);
λ κ°μ§ λ°©λ²μ νμ©λ²
1.
- ν΄λ¦ μ λ°λ‘ μ΄λνλ λ‘μ§ κ΅¬ν μμ μ¬μ©ν©λλ€.
- ex. Nav Bar, Aside Menu, μμ΄ν 리μ€νΈ νμ΄μ§μμ μμ΄ν ν΄λ¦ μ > μμΈ νμ΄μ§λ‘ μ΄λ
2. withRouterHOC
- νμ΄μ§ μ ν μ μΆκ°λ‘ μ²λ¦¬ν΄μΌ νλ λ‘μ§μ΄ μλ κ²½μ° withRouterHOC λ°©λ²μΌλ‘ ꡬνν©λλ€.
- ex. λ‘κ·ΈμΈ λ²νΌ ν΄λ¦ μ
- Backend APIλ‘ λ°μ΄ν°(User Info) μ μ‘
- User Data μΈμ¦ / μΈκ°
- response message
- Case 1 : νμ κ°μ λμ΄ μλ μ¬μ©μ > Main νμ΄μ§λ‘ μ΄λ
- Case 2 : νμ κ°μ μ΄ λμ΄ μμ§ μμ μ¬μ©μ > Signup νμ΄μ§λ‘ μ΄λ
쑰건문μ μμ§ μ£Όμ§ μμμ λ²νΌλ§ λλ¬λ λ©μΈνμ΄μ§λ‘ λμ΄κ°λ€.