리μ‘νΈ(React)μ λν κΈ°λ³Έμ μΈ λ΄μ©μΌλ‘ 리μ‘νΈμ λν κΈ°λ° μ 보μ μ»΄ν¬λνΈ, JSXμ λν λ΄μ©μ ν¬ν¨ν©λλ€. π
ννλ νν λ°λλΌ μλ°μ€ν¬λ¦½νΈλ₯Ό μ§λ λλμ΄ λ¦¬μ‘νΈμ λμ°©νλ€. μ κΉ μμλ΄€λλ°λ μ΄λ¦¬ μ΄λ©μ΄μ§νκ³ μ΄μΈνκ² μλ μΆλ€. κ·Έλ λ€λ©΄ 리μ‘νΈλ 무μμΈκ°? νμ΄μ€λΆμμ λ§λ 건 μκ² λλ° μ λλ‘ μμλ³Έ μ μ΄ μλ€. μ΄λ² ν¬μ€ν μμ κ°λ¨ν 리μ‘νΈμ λν΄ μμλ³΄κ³ , μ΄λ€ μλ¦¬λ‘ λμ€νλ μ΄μ λ°μλλμ§μ λν΄μλ Araboza.
리μ‘νΈ(React)λ μλ°μ€ν¬λ¦½νΈ λΌμ΄λΈλ¬λ¦¬μ νλλ‘ μ¬μ©μ μΈν°νμ΄μ€(UI)λ₯Ό λ§λ€κΈ° μν΄ μ¬μ©λλ€. μμμλ λ§νλ―μ΄, νμ΄μ€λΆμ μν΄ λ§λ€μ΄μ‘κ³ κ°λ³ κ°λ°μ λ° κΈ°μ
λ€ κ³΅λ체μ μν΄ μ μ§λ³΄μ λλ€.
리μ‘νΈμ λΉμ·νκ² μ¬μ©λλ Angular, Vueκ° MVC(Model-View-Controller) ArchitectureμΈλ° λ°ν΄, 리μ‘νΈλ μ€μ§ View λ§μ λ΄λΉνλ©°, κ·Έλ κΈ°μ μΆκ°μ μΈ third-party λΌμ΄λΈλ¬λ¦¬(React-router, Redux)λ₯Ό ν¨κ» μ¬μ©νλ€.
third-party library
κΈ°λ³Έμ μΌλ‘ μ 3μμ μλ―Έλ₯Ό κ°λ 'third-party' κ° ν¬ν¨λ 'third-party library'λ νλ‘κ·Έλλ°μ μν΄ λμμ΄ λλ νλ¬κ·ΈμΈμ΄λ λΌμ΄λΈλ¬λ¦¬ λ±μ λ§νλ€.
μ΄μ λν μμλ‘ λ¦¬μ‘νΈμ κ²½μ° React-routerλ₯Ό μ¬μ©νλλ°, SPA(Single Page Application) λ°©μμ μ±ννλ 리μ‘νΈμ κ²½μ° MPA(Multi Page Application) λ°©μμ²λΌ νμ΄μ§μ μ΄λμ΄ λΆκ°νΌνλ€. κ·Έλ κΈ°μ νμ΄μ§λ₯Ό μλ‘ λΆλ¬ λ€μ΄μ§ μκ³ λ³κ²½λ λΆλΆλ§ μμ νμ¬ νλμ νμ΄μ§μμ μΆλ ₯νκ² ν΄μ£Όλ λ λλ§ λΌμ΄λΈλ¬λ¦¬μΈ λΌμ°ν°λ₯Ό μ¬μ©νλ κ²μ΄λ€.
Virtual Dom
) π
리μ‘νΈμ κ°μ₯ ν° μ₯μ μ€ νλλ κ°μ λ(Virtual DOM)μ ν΅ν΄ μ€μ λμ μ κ·Όνλ λμ μ μΆμν μν¨ κ°μ²΄μ μ κ·Όνλ€λ κ²μ΄λ€. μ΄ λΆλΆμ΄ μ΄λ ν μ₯μ μ κ°λ μ§λ λ€μκ³Ό κ°μ μ΄μ κ° μλ€.
μ μμλ UIλ₯Ό λ³κ²½νλ κ³Όμ μμ κ°μλκ³Ό λΈλΌμ°μ μ μνλ₯Ό 보μ¬μ£Όλ λ΄μ©μ΄λ€. μ λ΄μ©μ μ€λͺ
νκΈ°μ μμ μ€μ λκ³Ό κ°μ λμ μ°¨μ΄μ μ λν΄ κ°λ¨ν μμ보μ. μ€μ λμ μ‘°μνλ κ²μ νλ©΄μ μ€μ λ‘ μ μ©νλ κ³Όμ μ΄κΈ°μ μ΄λ₯Ό μ§ννλ κ²μ μλμ μΌλ‘ λ¬΄κ±°μ΄ νλ‘μΈμ€μ μνλ€. κ·Έλ κΈ° λλ¬Έμ, μ΄λ₯Ό μ§μ μ‘°μνλ κ² λ³΄λ€ μ΄μ μ λ§λ€μ΄ λμ κ²½λ 볡μ¬λ³ΈμΈ κ°μ λμ μ΄λ₯Ό μ°μ μ μΌλ‘ μ μ©νκ³ μ€μ λκ³Ό μ΄λ ν μ°¨μ΄μ μ΄ μλ μ§ λΉκ΅νμ¬ λ μ‘°μμ μ§ννλ κ²μ΄ λ³΄λ€ λ κ°λ²Όμ΄ νλ‘μΈμ€μ ν΄λΉνλ κ²μ΄λ€.
λ€μ λμμμ μ μμλ₯Ό μ΄ν΄λ³΄λ©΄, μ°μ μνκ° λ³νλ κ²μ μΈμ§νκ³ μ΄μ λ°λΌ λ³νν λΆλΆμ μΆμ νμ¬ κ°μ λμ μ μ©νμμΌλ©° λ§μ§λ§μΌλ‘ λ³κ²½ λΆλΆμ λν΄ μ€μ λμ μ μ©νμ¬ μ΄λ₯Ό λ§λ¬΄λ¦¬ μ§λλ€. μ΄λ κ² λλ©΄ νΉνλ μ¬μ©μμ μΈν°λμ
μ΄ λ§μ SPA(Single Page Application)λ λ³νμ μμ΄ λ§κΈ° λλ¬Έμ, λ³νμ μμ νκΊΌλ²μ λ¬Άμ΄μ ν λ²μ μ§ννλ ννμΈ λ¦¬μ‘νΈκ° ν¨μ¬ μΎμ ν λΈλΌμ°μ νκ²½μ μ 곡νλ€.
Single Page Application
)SPA(Single Page Application)λ μλ²μμ μμ ν μλ‘μ΄ νμ΄μ§λ₯Ό λΆλ¬μ€μ§ μκ³ νμ¬ νμ΄μ§λ₯Ό λμ μΌλ‘ λ€μ μμ±ν¨μΌλ‘ νμ΄μ§λ₯Ό λ³κ²½νλ νμμ λ§νλ€. νμ΄μ€λΆμ νλ€λ³΄λ©΄ λ€λ₯Έ μ¬λμ΄ κ²μλ¬Όμ λκΈμ λ¬μμ λ, λ³λμ μλ‘κ³ μΉ¨ μμ΄ μ λ°μ΄νΈ λ¨μ λ³Ό μ μμλ€. κ·Έλ¬ν κΈ°λ₯μ΄ κ°λ₯ν μ΄μ λ νμ΄μ§κ° μ λ°μ΄νΈ λ λ, μλ‘μ΄ λ¬Έμ(HTML)λ₯Ό λ€μ μ€μΊνλ κ²μ΄ μλλΌ, μλ°μ€ν¬λ¦½νΈλ₯Ό νμ©νμ¬ λ€μκΈ λ³νκ° μΌμ΄λ λΆλΆμ λν΄μλ§ μμ μ μ§ννκΈ° λλ¬Έμ΄λ€.
SPAμ λ°λλλ κ°λ μΌλ‘ MPA(Multi Page Application)κ° μλλ°, λλ ν΄λΉ κ°λ μ νμ΄νΈλ³΄λμ κ°―μλ‘ λΉμ νμ¬ μ΄ν΄νκΈ°λ‘ νλ€. SPAμ κ²½μ° νμ΄νΈλ³΄λκ° νλκ³ μ¬λ¬κ°μ§ μ΄μμ λ°κΎΈλ©΄μ μμ νλ νμμ΄κ³ , MPAμ κ²½μ°λ μ¬λ¬κ°μ§μ νμ΄νΈλ³΄λμ μ΄μλ€μ΄ 미리 μμ±λμ΄ μλ μνμμ νμ΄νΈλ³΄λλ₯Ό λ³κ²½νλ νμμ΄λΌκ³ μ΄ν΄νλ€.
κ·Έλ κΈ°μ SPA νμμ λΉ λ₯Έ λ°μμ±, νλ©΄ μ ν λ±μ μΈ‘λ©΄μμ μ¬μ©μ μΉνμ μ΄κ³ μλμ μΌλ‘ μ μ§λ³΄μκ° μ½κ³ κ°λ°μλκ° λΉ λ₯΄λ©°, μ 체 νΈλν½ μμ΄ μ λ€λ μ₯μ μ΄ μλ€.
λ°λ©΄μ, μ²μ μ μκ³Ό λμμ λͺ¨λ 리μμ€λ₯Ό ν λ²μ λ°κΈ° λλ¬Έμ μ΄κΈ° ꡬλ μλκ° λ리λ€λ μ κ³Ό, κ²μμμ§ μ΅μ ν(SEO)κ° CSR λ°©μμΌλ‘ μ΄λ ΅λ€λ μ λ±μ΄ λ¨μ μΌλ‘ κΌ½νλ€.
λν 리μ‘νΈμ μ₯μ μΌλ‘ μ»΄ν¬λνΈ(Component)λ₯Ό νμ©νλ€λ μ μ΄ μλ€. μ»΄ν¬λνΈλ μ»΄ν¨ν° μννΈμ¨μ΄μμ λ€μ μ¬μ©ν μ μλ λ²μ©μ±μ μν΄ κ°λ°λ μννΈμ¨μ΄ κ΅¬μ± μμλ₯Ό μΌμ»«λλ€. κ·Έλ° μλ―Έμμ μ μ μλ―μ΄ λ¦¬μ‘νΈμμλ λ°λ³΅λλ UI κ΅¬μ± μμλ€μ νλμ μ»΄ν¬λνΈλ‘ μ§μ νμ¬ λ°λ³΅μ μΈ μμ
μ λ°©μ§νκ³ μ μ§λ³΄μμ μνν¨μ λΆμ¬νλ€. μ»΄ν¬λνΈμ νΉμ§μ μ 리νλ©΄ λ€μκ³Ό κ°λ€.
μ΄λ¬ν νΉμ§ λλΆμ μ»΄ν¬λνΈλ₯Ό νμ©νμ¬ UI ꡬμ±μ μ’ λ 체κ³μ μΌλ‘, κ³νμ μΌλ‘ ν μ μλ κ²μ΄λ€.
리μ‘νΈμλ λ κ°μ§μ μ»΄ν¬λνΈ μ μΈ λ°©μμ΄ μλλ° νλλ ν΄λμ€(Class)ν μ»΄ν¬λνΈ , λλ¨Έμ§ νλλ ν¨μν(Functional) μ»΄ν¬λνΈμ΄λ€. ν΄λμ€ν μ»΄ν¬λνΈμ ν¨μν μ»΄ν¬λνΈμ μν μ λΉμ·νμ§λ§, κ·Έ μ μΈ λ°©μμμ μ°¨μ΄λ₯Ό 보μΈλ€.
import React from 'react'
class Component extends React.Component { // extends : ν΄λμ€λ₯Ό λ€λ₯Έ ν΄λμ€μ μμμΌλ‘
render() {
return (
<div>
<h1>This is Class Component!</h1>
</div>
)
}
}
export default Component
ν΄λμ€ν μ»΄ν¬λνΈλ 보μ΄λ λ―μ΄ render()
ν¨μλ₯Ό μ¬μ©νκ³ JSX λ₯Ό λ°ννλ νμμ κ°λλ€. ν΄λμ€ν μ»΄ν¬λνΈλ λ€μκ³Ό κ°μ νΉμ§μ κ°λλ€.
import React from 'react'
const Component = () => {
return (
<div>
<h1>This is Functional Component!</h1>
</div>
)
};
export default Component
ν¨μν μ»΄ν¬λνΈλ ν΄λμ€ν μ»΄ν¬λνΈμ λ€λ₯΄κ² render()
ν¨μλ₯Ό μ¬μ©ν νμ μκ³ , λ³΄λ€ λ κ°λ΅νκ² μ»΄ν¬λνΈλ₯Ό μ μΈν μ μλ€λ μ₯μ μ΄ μλ€. ν¨μν μ»΄ν¬λνΈμ νΉμ§μ λ€μκ³Ό κ°λ€.
Hook
νμ©
μ΅κ·Όμλ ν¨μν μ»΄ν¬λνΈλ₯Ό λ μ νΈνλ μΆμΈμ΄λ€.
JSX(JavaScript Syntax Extension)λ₯Ό κ°λ¨νκ² λ§νλ©΄ "μλ°μ€ν¬λ¦½νΈ λ΄λΆμμ HTMLμ μ¬μ©ν κ²"μ΄λΌκ³ λ§ν μ μκ³ , μ νν λ§νμλ©΄ μλ°μ€ν¬λ¦½νΈ νμ₯ λ¬Έλ²μ΄λ€.
μ μμλ€μμ μλ°μ€ν¬λ¦½νΈ λ΄λΆμ HTML ꡬ쑰μ μ½λκ° μμ±λ κ²μ νμΈν μ μλ€. μ΄λ κ² μμ±λ μ½λλ€μ λ°λ²¨(Babel)μ΄λΌλ μλ°μ€ν¬λ¦½νΈ μ»΄νμΌλ¬λ₯Ό ν΅ν΄ μΌλ° μλ°μ€ν¬λ¦½νΈ ννμ μ½λλ‘ λ³νλλ€. μ΄λ κ² JSXλ‘ μμ±νλ©΄, DOMκ³ΌEvent
λ₯Ό νμ©νλ κ²λ³΄λ€ μ’ λ μ§κ΄μ μΌλ‘ νμΈν μ μκΈ°μ, κ°λ° κ³Όμ μμ ν¨μ¨μ μ¦κ°μν¨λ€.
JSXμ λ¬Έλ²μ νΉμ§μΌλ‘ μλ°μ€ν¬λ¦½νΈ ννμ{}
μμ μμ±νλ κ²κ³Ό, Self Closing tag κ·Έλ¦¬κ³ μμ±ν λ, νλμ μ»΄ν¬λνΈλ λͺ¨λ μμλ€μ κ°μΈλ νλμ μ΅μμ μμκ° μ‘΄μ¬ν΄μΌ νλ€λ μ λ±μ΄ μλ€.
// μ΅μμ μμ μμ return ( <div> <h1>Hello, World!</h1> <div>Welcome to JSX!</div> </div> ) // μ΅μμ μμ μμ : μ€λ₯ λ°μ return ( <h1>Hello, World!</h1> <div>Welcome to JSX!</div> )
μ΅μμ μμκ° μ‘΄μ¬νμ§ μλ κ²½μ°, λ€λ₯Έ νκ·Έλ‘ λννλ κ²μ΄ κΊΌλ €μ§λ κ²½μ° Fragmentsλ₯Ό νμ©νμ¬ νμμμ λνμ μ§νν μ μλ€. κ·Έλ κ² λλ©΄ μ€μ λ‘ λ λλ§ λκ³ λ λ€μλ κ°μΈλ νκ·Έλ μ‘΄μ¬νμ§ μλ κ²°κ³Όλ₯Ό 보μ¬μ€λ€.// μ΅μμ μμ Fragments return ( <> <h1>Hello, World!</h1> <div>Welcome to JSX!</div> </> )
react-router
) πΊοΈμμμ SPA λ°©μμ λν΄ μΈκΈνλ©΄μ, κ΄λ ¨ κ°λ
μΌλ‘ λ±μ₯νλ λΌμ°ν°μ λν΄ μμ보μ. SPAλ λ§ κ·Έλλ‘ νλμ νμ΄μ§ λ§μΌλ‘ ꡬμ±λ μ΄ν리μΌμ΄μ
μ μλ―Ένλλ°, μ΄κ²μ΄ 곧 ν μ’
λ₯μ νλ©΄ λ§μ΄ μ‘΄μ¬νλ κ²μ μλλ€. λΉμ°νλ, SPA λν μ§μ λΈλΌμ°μ μ APIλ₯Ό μ¬μ©νκ³ μνλ₯Ό μ€μ ν΄μ λ€λ₯Έ λ·°λ₯Ό 보μ¬μ€ μ μλ€.
μ΄λ κ² λ€λ₯Έ μ£Όμμ λ°λΌ λ€λ₯Έ λ·°λ₯Ό 보μ¬μ£Όλ κ²μ λΌμ°ν
(Routing)μ΄λΌκ³ νκ³ , 곡μμ μλμ§λ§ 리μ‘νΈμ κ²½μ°μ μ΄μ μμλ³Ό 리μ‘νΈ λΌμ°ν°(react-router
)λΌλ μ¨λ νν° λΌμ΄λΈλ¬λ¦¬λ₯Ό μ£Όλ‘ μ¬μ©νλ€.
μ°μ CRA νλ‘μ νΈλ₯Ό μμ±νλ€λ μ μ νμ μ΄νμ κ³Όμ μ μμ보μ. 리μ‘νΈ λΌμ°ν°λ₯Ό μ¬μ©νκΈ° μν΄μλ λ³λμ μ€μΉ κ³Όμ μ νμλ‘ νλ€.
npm install react-router-dom --save
CRA νλ‘μ νΈλ₯Ό μ€μΉνκ³ , ν΄λΉ λλ ν λ¦¬λ‘ μ΄λνμ¬, ν°λ―Έλλ‘ ν΄λΉ λͺ
λ Ήμ΄λ₯Ό μ€ννμ¬ λ¦¬μ‘νΈ λΌμ°ν°λ₯Ό μ€μΉνλ€. μ€μΉκ° λλ¬λ€λ©΄, μ΄μ μ»΄ν¬λνΈλ₯Ό ꡬνν μ°¨λ‘λ€.
import React from 'react';
import {
BrowserRouter as Router,
Switch,
Route,
} from 'react-router-dom';
import Login from './pages/Login/Login';
import Main from './pages/Main/Main';
class Routes extends React.Component {
render() {
return (
<Router>
<Switch>
<Route exact path="/" component={Login} />
<Route exact path="/main" component={Main} />
</Switch>
</Router>
)
}
}
export default Routes;
μ μμλ λΌμ°ν° μ»΄ν¬λνΈλ₯Ό ꡬνν μμμ΄λ€. μ°μ μ΅μλ¨μμ 리μ‘νΈ λͺ¨λμ λΆλ¬μ€κ³ , λΌμ°ν°μμ BrowserRouter
, Switch
, Route
λ₯Ό λΆλ¬μ¨λ€. μ μΈ κ°μ§λ μλμ μ»΄ν¬λνΈ μμ±μ μ¬μ©λ κ²μ΄λ€.
κ·Έλ¦¬κ³ μ΄μ΄μ νμ΄μ§μ ν΄λΉνλ μ»΄ν¬λνΈλ€μ κ°κ°μ μμΉμμ λΆλ¬μ¨λ€. μ μμμμ Login
κ³Ό Main
μ΄λΌλ μ»΄ν¬λνΈλ₯Ό λΆλ¬μλ€.
κ·Έλ€μμ 본격μ μΌλ‘ μ»΄ν¬λνΈλ₯Ό μμ±νλ€. μ μμμμ μ»΄ν¬λνΈ μμ±μ ν΄λμ€ μ»΄ν¬λνΈ λ°©μμ μ¬μ©νμ¬ μμ±νλ€. μ°μ Router
λ‘ μ μλ BrowserRouter
λ₯Ό ν΅ν΄ μ 체 λΌμ°νΈλ€μ λ¬Άμ΄μ€λ€. κ·Έλ¦¬κ³ κ·Έ μμ Switch
λ₯Ό ν΅ν΄ μ΄λν Route
λ€μ λ¬Άμ΄μ€λ€. λ§μ§λ§μΌλ‘ κ·Έ λ΄λΆμ Route
λ₯Ό μμ±νλ κ²μΌλ‘ μ»΄ν¬λνΈ μμ±μ λ§μΉλ€. μ μμμ κ²½μ° μ΄κΈ° λ§ν¬λ₯Ό Login
μΌλ‘ μ€μ νλ€.
μ΄λ κ² Routes
μ»΄ν¬λνΈλ₯Ό μμ±νμμΌλ©΄, index.js
μ λ λλ§ λΆλΆμ λ³κ²½ν΄μ€λ€.
ReactDOM.render(<Routes />, document.getElementById('root'));
μ μμλ₯Ό 보면 Routes
μ»΄ν¬λνΈλ₯Ό λ λλ§νλ κ²μΌλ‘ λ³κ²½λμ΄μλ€. μ΄λ κ² μ€μ νλ©΄, Routes
μ»΄ν¬λνΈ λ΄λΆμμ μ€μ ν default
κ°μ λ§ν¬λ‘ μ΄κΈ° νμ΄μ§κ° μ€μ λκ³ , μ΄ν <Link>
μ»΄ν¬λνΈ νΉμ this.props.history.push()
λ₯Ό ν΅ν΄ νμ΄μ§λ₯Ό μ΄λν μ μλ€.
<Link>
μ»΄ν¬λνΈμ this.props.history.push()
μ λ κ°μ§ λ°©λ²μ 리μ‘νΈ λΌμ°ν°λ₯Ό μ΄μ©νμ¬ λ§ν¬λ₯Ό μ΄λν μ μλ λ κ°μ§ λ°©λ²μ΄λ€. μ κ΅³μ΄ λ κ°μ§ λ°©λ²μ΄ μ‘΄μ¬νλμ§ μ¬μ©λ²κ³Ό ν¨κ» μ°¨μ΄μ μ μμ보μ.
μ°μ κ°κ°μ μ¬μ©λ²μ λ€μκ³Ό κ°λ€.
// <Link> // λΆλ¬μ€κΈ° import { Link } from 'react-router-dom' <Link to="/signup">νμκ°μ </Link>
// this.props.history.push()' // λΆλ¬μ€κΈ° import { withRouter } from 'react-router-dom' // ν¨μ μμ± goToMain = () => { this.props.history.push('/main'); } // μ΄λ²€νΈμ μΆκ° <button className="loginBtn" onClick={this.goToMain}>
μμμ λ³Ό μ μλ κ°μ₯ ν° μ°¨μ΄μ μ ν¨μλ₯Ό μ¬μ©νλ€λ μ μΌ κ²μ΄λ€.Link
μ κ²½μ° λ°λ‘ μ»΄ν¬λνΈλ₯Ό μΆκ°νμ¬ μ΄λ₯Ό 쑰건 μμ΄ λ°λ‘ μ€νν μ μμ§λ§,this.props.history.push()
μ κ²½μ° ν¨μλ₯Ό ν΅ν΄ μμ±νμ¬ ν΄λΉ κ³Όμ μμ λ‘μ§μ μΆκ°ν μ μλ€λ μ μ΄ μλ€. κ·Έλ λ€, λ‘μ§μ μΆκ° κ°λ₯ μ λ¬΄κ° λ κ°μ§ λ°©μμ ν° μ°¨μ΄μ μ΄λ€.
λνLink
μ κ²½μ°, λ λλ§ μ΄ν<a>
νκ·Έλ‘ λ³νλλ°, μ¬μ©μ μμ΄ κ·Έ μ°¨μ΄μ μ΄ μ‘΄μ¬νλ€.<a>
νκ·Έλ₯Ό ν¬ν¨ν μΈ κ°μ§μ μ¬μ© λ°©λ²μ λ€μκ³Ό κ°μ΄ μ 리ν μ μλ€.
Link
: λ³λμ λ‘μ§μ΄ νμ μλ νμ΄μ§ λ΄ μ΄λ
ex) νλ‘ν νμΈ λ±this.props.history.push()
: λ‘μ§μ΄ νμν νμ΄μ§ λ΄ μ΄λ
ex) λ‘κ·ΈμΈ λ±<a>
νκ·Έ : μΈλΆ λ§ν¬λ‘μ μ΄λ