🚀 Frontend Framwork
와 Library
의 등장 배경
👉 UI
(User Interface, 보여지는 것) 와 UX
(User Experience, 할 수 있는 것) 의 니즈가 증가하면서 웹 페이지(Web Page)라는 단어보다 웹 애플리케이션이(Web Application)이 발전했다
(사용자와의 상호작용이 증가).
❗ Web의 발전
으로 UI, UX의 생산성을 높이도록 요구 ➡ Frontend Framework(Library)의 사용 필요성 증가
👉 애플리케이션의 규모가 커지고 다양한 UI, UX를 구현하기 위해서는 기존 방법(DOM, jQuery)으로는 애플리케이션을 개발하고 코드를 유지보수 하는 것이 어려워졌다.
👉 화면의 많은 DOM 요소들에 직접 접근해서 조작하고 관리하기란 쉽지 않다. jQuery도 결국엔 쉽게 DOM에 접근해서 조작을 가능하게 하는 메소드의 모음이기 때문에 마찬가지이다.
jQuery
html에서 Client Side 조작을 간락히 해주는 것. 그러나 기능 측면(속도)에서 차별성이 없기 때문에 사장되며 그 대안으로 다양한Frontend Framework
와Library
가 등장
👉 규모가 커지고 복잡한 애플리케이션을 개발하며 생산성을 향상
시키고 많은 양의 데이터 관리와 코드 유지 보수를 더욱 편리
하게 하기 위해 다양한 Frontend Framework(Library)가 등장하게 된다.
그 중 가장 많이 쓰이는 세 가지가 Angular
, Vue
, React
이다.
🚀 대표적 Frontend Framwork
와 Library
👉 Framwork
⏩ Angular
, Vue
👉 Library
⏩ React
❗ React 라이브러리를 사용하는 이유
직접 순수 자바스크립트로 개발을 구현해보는 과정에서 UI가 복잡해지면서 한계를 느낌 ➡ Framework와 Library를 찾아보다가 React는 생태계가 활성화
되어 있기 때문에 구글링이 편리하며 사용자가 많아서 장기적인 관점에서 잠재력이 큰 Library라고 생각하여 사용, UI를 위한 Library라는 점에서 프론트엔드 개발자로써 매력있게 다가왔다
👉 페이스북
에서 개발하고 관리하는 사용자 인터페이스(UI)를 만들기 위한 JavaScript 라이브러리.
❗ 리액트는 UI 기능만 제공한다.
👉 리액트를 사용하는 가장 큰 이유 중 하나는 UI를 자동으로 업데이트해 준다는 점이다.
👉 리액트는 가상 돔(Virtual Dom)
을 통해 UI를 빠르게 업데이트한다. 가상 돔은 이전 UI 상태를 메모리에 유지해서, 변경될 UI의 최소 집합을 계산하는 기술이다. 이 기술 덕분에 불필요한 UI 업데이트는 줄고, 성능은 좋아진다.❗ 가상돔을 통해 전체가 아닌 바뀐 부분(변경될 UI의 최소 집합)만
업데이트 시켜준다.
👉 컴포넌트(Component, 재사용이 가능한 최소한의 UI단위)의 사용을 통해, 코드의 일관성(간결) 및 코드의 유지보수가 용이해진다.
Node.js
👉 Node.js 는 자바스크립트가 브라우저 밖(ex. 서버)에서도 동작하게 하는 환경을 의미.
👉 리액트 애플리케이션은 웹 브라우저에서 실행되는 코드이므로 Node.js와 직접적인 연관은 없지만, 프로젝트를 개발하는 데 필요한 주요 도구들(ex. 바벨, 웹팩)이 Node.js 기반이기 때문에 반드시 설치해야 한다.
👉 Node.js를 설치하면 npm(node package manager) 이 자동으로 설치 되는데 npm을 사용하기 위해서는 노드(Node.js)가 설치되어 있어야 한다.
👉 터미널에서$ node -v
명령어를 실행 함으로써 Node.js 의 버전을 확인할 수 있다. 노드 버전이 정상적으로 확인되면 설치도 정상적으로 이루어진 것이다.
npm
👉 Node 기반의 패키지를 사용하려면 npm(node package manager)이라는 패키지 도구가 필요.
👉 npm 을 통해 다양한 패키지를 설치하고 버전을 관리할 수 있다.
👉 npm 버전을 확인하는$ npm -v
명령어를 통해 설치가 정상적으로 이루어졌는지 확인해볼 수 있다.
👉 리액트 프로젝트를 시작하는데 필요한 개발 환경을 세팅 해주는 도구(toolchain)
❗ CRA는 리액트로 웹 애플리케이션을 만들기 위한 환경을 제공
👉 직접 개발 환경을 구축하기 어렵기 때문에 CRA(Create-React-App)
가 만들어졌다.
👉 CRA를 이용하면 하나의 명령어로 리액트 개발환경을 구축할 수 있다.
✨(CRA를 사용한 이유, 쉽게 개발환경을 구축할 수 있기 때문에)✨
CRA에는
바벨
과웹팩
과 같이 리액트 애플리케이션 실행에 필요한 다양한 패키지가 포함되어 있으며, 필수라고 할 수 있는 개발 환경도 구축해 준다. 이러한 개발 환경을 직접 구축할 경우 시간이 오래 걸릴 뿐 아니라 유지 보수도 해야한다. CRA를 이용하면 개발 환경 세팅을 해주기 때문에 기존 기능을 개선하거나 새로운 기능을 추가했을 때 패키지 버전만 올리면 된다.
👉 CRA 설치
// 1. Desktop - [to_do_list (=폴더명1)] 진입 cd Desktop/(to_do_list) // 2. [to_do_react (=폴더명2)] 프로젝트 설치 npx create-react-app (to_do_react) ❗ [폴더명2]으로 프로젝트를 설치한다는 것은 해당 폴더(=westagram-react)를 만들고(깃 자동으로 연동되어 있음) 그 안에 CRA가 설치된다는 뜻 // 3. (to_do_react) 프로젝트 진입 cd (to_do_react) ❗ [~Desktop/to_do_list/to_do_react] 경로가 설정됨 // 4. 로컬 서버 띄우기 npm start ❗ vsCode에서 작성 후 로컬서버를 띄울때는 터미널 창에서 npm start 명령하기!!!!!!!
👉 CRA 폴더/파일 구성
:: node.modules - package.json - .gitignore
1)
node.modules
- CRA 를 구성하는 모든 패키지 소스 코드가 존재하는 폴더
2)
package.json
- CRA 기본 패키지 외 추가로 설치된 라이브러리/패키지 정보(종류, 버전)가 기록되는 파일 (third-party 추가 / ex. react)
- 모든 프로젝트마다 package.json 하나씩 존재
dependencies
- 리액트를 사용하기 위한 모든 패키지 리스트, 버전 확인 가능
- 실제 코드는
node.modules
폴더에 존재- node.modules 외에 package.json 에서 이중으로 패키지를 관리하는 이유는, Git Hube 업로드 시, 무겁지 않게 하기 위해
scripts
- run : 프로젝트를 development mode(개발 모드) 실행을 위한 명령어.
npm run start
.- build : 프로젝트 production mode(배포 모드) 실행을 위한 명령어. 서비스 상용화.
- 참고) package.json vs. package-lock.json
3)
.gitignore
.gitignore
파일에 github 에 올리고 싶지 않은 폴더와 파일을 작성할 수 있다.push
를 해도..gitignore
파일에 작성된 폴더와 파일은 올라가지 않는다
:: index.html - index.js - App.js
1) public -
index.html
<div id="root"></div> // id 가 'root'인 태그 (화면에 보여지는 위치를 지정)
2) src -
index.js
- React의 시작 (Entry Point) / Rendering해주는 역할
ReactDOM.render( <Routes /> , document.getElementById('root'))
- ReactDOM.render 함수의 인자는 두 개
- 첫 번째 인자는 화면에 보여주고 싶은 컴포넌트(src ➡
Routes.js
)- 두 번째 인자는 화면에 보여주고 싶은 컴포넌트의 위치(public ➡
index.html
)- (이름 함부로 수정하면 안 됨)
❗ SPA(Single Page Application - html 페이지가 1개인 애플리케이션)의 개념 적용.
index.js
내 1개의Routes.js
를<Routes />
에 적용하여 1개의 페이지가 web 화면에 보여지고 해당 폴더 내부에서 여러 페이지를 연결하는 원리. =Routing3) src -
Routes.js
/(페이지).js
- 현재 화면에 보여지고 있는 초기 컴포넌트
<Routes />
컴포넌트가 최상위 컴포넌트로index.js
내 자리에 위치하게 된다.- Routes.js 페이지 내에 페이지 수만큼 html 파일이 존재
Login.js
또는Main.js
처럼 화면에 보여주고자 하는 페이지 단위의 컴포넌트를 생성한 후 JSX로 작성
:: 기타 폴더 구성
1) public 폴더
- index.html
- images - 이미지 파일 관리
- data - mock data 관리 (추후 세션을 통해 다룰 예정)
2) src 폴더
- components - 공통 컴포넌트 관리
- pages - 페이지 단위의 컴포넌트 폴더로 구성
- Login -
Login.js
,Login.scss
- Main-
Main.js
,Main.scss
- styles 폴더
reset.scss
- css 초기화commom.scss
- 공통으로 사용하는 css 속성 정의 (ex. font-family, theme color)- 참고) components vs. pages
- 여러 페이지에서 동시에 사용되는 컴포넌트의 경우 components 폴더에서 관리. (각 페이지마다 컴포넌트 단위로 적용)
(ex. Header, Nav, Footer)- 페이지 컴포넌트의 경우 pages 폴더에서 관리. (ex. 인스타 Feed - 피드가 update될때마다 피드 내용만 바뀜)
- 해당 페이지 내에서만 사용하는 컴포넌트의 경우, 해당 페이지 컴포넌트 폴더 하위에서 관리.
👉 재활용 가능한 UI 구성 단위
ex) westagram 메인 페이지
예를 들어, westagram main 페이지를Component
로 나눈다면,
크게Nav Component
와Main Component
, 그리고 Main 컴포넌트 안에는Feed Component
와MainRight Component
로 나눌 수 있다.
👉 컴포넌트의 특징 ✨
- 재활용(재사용)하여 사용할 수 있다.
- 코드 유지보수에 좋다.
- 해당 페이지가 어떻게 구성되어 있는지 한 눈에 파악하기 좋다.
- 컴포넌트는 또 다른 컴포넌트를 포함할 수 있다. (부모 컴포넌트 - 자식 컴포넌트)
👉 Class Component
vs. Functional Component
컴포넌트를 선언하는 방식에는 두 가지가 있다.
- Class형 컴포넌트(Class Component)
- 함수형 컴포넌트(Functional Component)
1) Class Component
import React from 'react' class Component extends React.Component { render() { return ( <div> <h1>This is Class Component!</h1> </div> ) } } export default Component
❗ 클래스형 컴포넌트에서는
render
함수(메소드)가 꼭 있어야 하고, 그 안에 보여 주어야 할 JSX를 반환한다.2) Functional Component
import React from 'react' const Component = () => { return ( <div> <h1>This is Functional Component!</h1> </div> ) }; export default Component
❗ 함수형 컴포넌트가 보기에는 훨씬 간단하고 작성하기 편리한 장점이 있다. (많이 사용)
👉 JSX 정의
- JavaScript Syntax Extension
- JSX란 리액트에서 사용하는 자바스크립트 확장 문법
(html도 아니고 js도 아니다)- JSX로 작성한 코드는 브라우저에서 동작하는 과정에서 바벨(Babel)을 사용하여 일반 자바스크립트 형태의 코드로 변환된다.
👉 JSX 장점
- HTML 태그를 그대로 사용하기 때문에 보기 쉽고 익숙하다.
- HTML 태그를 사용하는 동시에 자바스크립트도 JSX 안에서 동작하게 할 수 있다.
vs. DOM + Event
👉 JSX 특징
- 자바스크립트 표현 :
{ ... javascript... }
class
➡className
- Inline Styling :
<div style={{color : "red"}}>Hello React</div>
- Self Closing tag :
<div></div>
➡<div />
- 모든 요소를 감싸는 최상위 요소 (cf. React Fragments :
<> ... </>
)
❗ JSX의 큰 특징 중 하나는 내부 요소들을 감싸는 최상위 요소가 있어야 한다. Fragments는 DOM에 별도의 노드를 추가하지 않고 하나의 컴포넌트 안에 여러 요소(자식)들을 간단하게 그룹화 할 수 있는 기능이다. 요소들을 감싸는div
태그의 불필요한 생성을 막을 수 있어 유용하게 사용된다.<> <div className="loginBtn" onClick={() => console.log("click")}>Login</div> <br /> <div style={{backgroundColor: "grey", height: "10px"}} /> </>
👉 페이지가 한 개인 애플리케이션 ➡ react 프로젝트에서 .html
파일의 갯수는 1개이다
👉 한 개의 웹페이지(html
) 안에서 여러 개의 페이지를 보여주는 방법은 Routing
이 있다.
👉 라우팅(Routing)
이란 다른 경로(url 주소)에 따라 다른 View(화면)를 보여주는 것 이다.
👉 리액트 자체에는 이러한 기능이 내장되어있지 않다(리액트가 Framework 가 아닌 Library 로 분류되는 이유)
👉 React-router
는 리액트의 라우팅 기능을 위해 가장 많이 사용 되는 라이브러리이다. (cf. Third-party Library)
React Router
Create React App(CRA)에 특별히 routing을 위한 로직이 들어있지 않기 때문에, 가장 인기 있는 routing solution인react-router
를 추가해서 routing을 구현할 수 있다.🚗 react-router 설치
npm install react-router-dom --save
🚗 routes 컴포넌트 구현하기
---jsx--- // 필요한 패키지 import import React from 'react'; import { BrowserRouter as Router, Switch, Route, } from 'react-router-dom'; // 필요한 component import Login from './pages/Login/Login'; import Signup from './pages/Signup/Signup'; import Main from './pages/Main/Main'; import "./pages/Login/Login.scss"; import "./pages/Main/Main.scss"; class Routes extends React.Component { render() { return ( <Router> <Switch> <Route exact path="/" component={Login} /> //default 페이지는 '/'로 표현 <Route exact path="/signup" component={Signup} /> <Route exact path="/main" component={Main} /> </Switch> </Router> ) } } export default Routes;
🚗 index.js
---jsx--- // (1) 필요한 패키지(고정) - 노드모듈에서 확인 가능 import React from "react"; import ReactDOM from "react-dom"; // (2) 필요한 컴포넌트 - Routes 페이지 1개를 고정/연동 import Routes from "./Routes"; // (3) 연동되는 css 파일 import "./index.scss"; import "./styles/common.scss"; import "./styles/reset.scss"; ReactDOM.render(<Routes />, document.getElementById("root")); // 화면에 보여줄 컴포넌트(Routes(default페이지), =SPA), 컴포넌트가 있는 위치(root가 있는 곳) // 이 페이지는 index.html 페이지와 Routes.js 파일을 연결해주는 역할 //component - 재사용 가능한 UI 단위(class형-직관적 / function형 - 많이 사용)
❗ CRA로 만든 앱에 routing 기능을 적용하려면
index.js
에 routing을 설정한 컴포넌트(<Routes />
)를 적용해줘야 한다.
👉 Route 이동하기
Route 이동하는 방법은 두 가지가 있다.
<Link>
컴포넌트 사용하는 방법withRouterHOC
로 구현하는 방법
🚗
<Link>
컴포넌트 사용하는 방법---jsx--- 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; // <Link to="(목적경로)"></Link>를 텍스트에 감싸줘도 되고, 태그에 감싸줘도 된다 // <Link to="/signup"><div>회원가입><div></Link>
Routes.js
에서 설정한 path로 이동하는 첫 번째 방법은<Link>
컴포넌트를 사용하는 방법이다.react-router-dom
에서 제공하는<Link>
컴포넌트는 DOM에서<a>
로 변환(Compile) 된다.cf)
<Link>
=<a>
(<a>
태그와 마찬가지로<Link>
태그도 지정한 경로로 바로 이동시켜주는 기능)
cf) JSX - Babel - JavaScript❗
<a>
vs.<Link>
-<a>
- 외부 사이트로 이동하는 경우
-<Link>
- 프로젝트 내에서 페이지 전환하는 경우🚗
withRouterHOC
로 구현하는 방법---jsx--- import React from 'react'; import { withRouter } from 'react-router-dom'; class Login extends React.Component { goToMain = () => { this.props.history.push('/signup'); } ** // 실제 활용 예시 // 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
) 에 접근해서 이동할 수 있다.- 받은
history
의push
메서드의 인자로Routes.js
에서 설정한 path를 넘겨주면, 해당 라우트로 이동할 수 있다.- 이 컴포넌트(Login 컴포넌트)에서 props에 route 정보(
history
)를 받으려면 export하는 컴포넌트에withRouter
로 감싸주어야 한다.- 이렇게
withRouter
와 같이 해당 컴포넌트를 감싸주는 것을 Higher Order Component (이하 HOC) 라고 한다.🚗 두 가지 방법의 활용법
1.<Link>
- 클릭 시 바로 이동하는 로직 구현 시에 사용.
- ex. Nav Bar, Aside Menu, 아이템 리스트 페이지에서 아이템 클릭 시 > 상세 페이지로 이동
2.withRouterHOC
- 페이지 전환 시 추가로 처리해야 하는 로직이 있는 경우 withRouterHOC 방법으로 구현.
- ex. 로그인 버튼 클릭 시
- Backend API로 데이터(User Info) 전송
- User Data 인증 / 인가
- response message
- Case 1 : 회원 가입되어 있는 사용자 > Main 페이지로 이동
- Case 2 : 회원 가입이 되어 있지 않은 사용자 > Signup 페이지로 이동
새봄님 정리 완전 깔끔해요👍 저 이번 주말에 리액트 첨 건드려볼건데 새봄님 포스트가 도움이 많이될 것 같아요ㅎㅎ