: 프론트엔드 개발을 위한 JavaScript 오픈 소스 라이브러리.
1. 선언형
HTML/CSS/JS로 나눠서 적기 보다는 JSX를 사용해 하나의 파일에 명시적으로 작성하는 선언형 프로그래밍을 지향함.
2. 컴포넌트 기반
하나의 기능 구현을 위해 여러 종류의 코드를 묶어둔 컴포넌트를 기반으로 개발함.
컴포넌트로 분리하면 독립적, 재사용성이 좋아지기에 기능 자체에 집중하여 개발 가능함.
3. 범용성(다양한 곳에서 활용)
JS 프로젝트 어디든 적용 가능함.
JavaScript XML의 줄임말임. React에서 UI를 구성할 때 사용하는 문법으로 JavaScript를 확장한 문법임. 이 문법을 이용해서 React 엘리먼트를 만들 수 있음. (JSX 없이도 React 요소를 만들 수 있지만 코드가 복잡하고, 가독성이 떨어짐.)
Babel은 JSX를 브라우저가 이해할 수 있는 JavaScript로 컴파일함.
컴파일 후, JavaScript를 브라우저가 읽고 화면에 렌더링할 수 있음.
React에서는 DOM과 다르게 CSS, JSX 문법만을 가지고 웹 애플리케이션을 개발할 수 있음.
브라우저 DOM 엘리먼트와 달리 React 엘리먼트는 일반 객체(plain object)임.
<div id="root"></div>
이 안에 들어가는 모든 엘리먼트를 React DOM에서 관리하기 때문에
이것을 “루트(root)” DOM 노드라고 부름.
React 엘리먼트를 루트 DOM 노드에 렌더링하려면 둘 다 ReactDOM.render()
로 전달하면 됨.
const element = <h1>Hello, world</h1>;
ReactDOM.render(element, document.getElementById('root'));
React 엘리먼트는 DOM 노드 혹은 컴포넌트를 표현하는 JavaScript의 일반 불변 객체(Plain Immutable Object)에 해당함.
...(X)....
<div></div>
<div></div>
...(O)....
<>
<div></div>
<div></div>
</>
엘리먼트 클래스 사용 시, className 으로 표기.
JavaScript 표현식 사용 시, 중괄호( { } ) 이용.
: 중괄호를 사용하지 않으면 일반 텍스트로 인식함.
사용자 정의 컴포넌트는 대문자로 시작.
: React 엘리먼트가 JSX로 작성되면 "대문자"로 시작해야 함.
소문자로 시작하게 되면 일반적인 HTML 엘리먼트로 인식을 하게 됨.
조건부 렌더링에는 삼항 연산자를 사용.
여러 개의 HTML 엘리먼트를 표시할 때 map() 함수를 이용.
: map 함수를 사용할 때는 반드시 "key" JSX 속성을 넣어야 함.
key는 데이터가 가지는 고유한 id 값(식별자)을 활용함.
(보통 요소의 id(제일 권장)나 index를 넣음. 근데 shortid 모듈
을 이용하면 더 쉽게 key를 만들 수 있음.)
npm install shortid
-->
import shortid from 'shortid'
-->
요소 = { id: shortid(), ..}
-->
map…< key={el.id} >
const Component = () => {
return (
<>
<div> 1 </div>
<div> 2 </div>
</>
)
};
하나의 기능 구현을 위한 여러 종류의 코드 묶음, UI를 구성하는 필수 요소.
모든 리액트 애플리케이션은 최소 한 개의 컴포넌트를 가지고 있으며, 이 컴포넌트는 애플리케이션 내부적으로는 근원(root)이 되는 역할을 함. 이 최상위 컴포넌트는 근원의 역할을 하므로 다른 자식 컴포넌트를 가질 수 있음. 이 계층적 구조(hierarchy)를 트리 구조로 형상화할 수 있음.
아래 화면을 출력하기 위해서 작성한 코드 살펴보기.
let langs = ["JavaScript", "HTML", "Python"];
1)
return (
<div>
{langs.map((it) => {
return <p>{it}</p>;
})}
</div>
);
2)
return (
<div>
{langs.map((it) => (
<p>{it}</p>
))}
</div>
);
{ return … } = ( … )
👈👈
1)은 중괄호를 사용하여 JavaScript를 내부에 표현해주었기 때문에 올바르게 작동함.
주의할 점은 중괄호를 쓰게 되면 JavaScript 코드로 인지하므로 꼭 return 이 존재해야 함. return 이 없다면 undefiend 를 반환하게 됨.
정리하자면 중괄호({}
)를 묶으면 function () {}
와 같으며, 소괄호(()
)로 묶으면 () 안의 값이 return값이 됨.
2)는 () 를 사용했기 때문에 () 안의 값이 return 값이 됨.
리액트 SPA를 쉽고 빠르게 개발할 수 있도록 만들어진 툴 체인임.
설치 명령어: npx create-react-app 폴더이름
: 랜덤 명언 앱(실습)
Math.random()
은 0~1사이의 난수.
[활용하기]
Math.random() * n(정수)
--> 소수점 버림 --> 0 ~ n-1
까지의 정수가 랜덤하게 나옴.
Q. 만약 두 값 사이의 수를 생성하고 싶다면? (최대값 불포함 or 최대값 포함)
function getRandomInt(min, max) {
min = Math.ceil(min);
max = Math.floor(max);
return Math.floor(Math.random() * (max - min)) + min;
//최댓값은 제외, 최솟값은 포함
}
function getRandomIntInclusive(min, max) {
min = Math.ceil(min);
max = Math.floor(max);
return Math.floor(Math.random() * (max - min + 1)) + min;
//최댓값도 포함, 최솟값도 포함
}
*많이 사용하는 아이콘 사이트 : Font Awesome
+jsx에서 작성하기 --> <i className="far fa-comment-dots"></i>
SPA는 서버로부터 완전히 새로운 페이지를 불러오는 것이 아니라,
화면을 업데이트하기 위해 필요한 데이터만 서버에서 전달받아 브라우저에서 해당하는 부분만 업데이트하는 방식으로 작동하는 웹 애플리케이션이나 웹 사이트를 말함.
전체 페이지가 아니라 필요한 부분의 데이터만 받아서 화면을 업데이트 하니까 사용자와의 interaction에 빠르게 반응함.
서버 과부하 문제가 현저하게 줄어듬.
SPA 경우, JS 파일의 크기가 큼. JS 파일을 기다리는 시간으로 인해 첫 화면 로딩 시간이 길어짐.
검색 엔진 최적화(SEO)가 좋지 않음. SPA의 경우, HTML 파일은 별다른 자료가 없기 때문에 검색 엔진이 적절히 동작하지 못 함.
SPA는 하나의 페이지를 가지고 있지만 사실 한 종류의 화면만 사용하지 않음.
또한 이 화면에 따라 "주소"도 달라짐.
이렇게 다른 주소에 따라 다른 뷰를 보여주는 과정을 "경로에 따라 변경한다."라는 의미로 라우팅(Routing) 이라고 함.
React에서 npm으로 React Router DOM을 설치
--> npm install react-router-dom@5.3.0
React Router DOM
를 이용하여 SPA
를 구현
: 라우팅 구조짜기
BrowserRouter
BrowserRouter는 웹 애플리케이션에서 HTML5의 History API를 사용해 페이지를 새로고침하지 않고도 주소를 변경할 수 있는 역할을 해줌.
BrowserRouter가 상위에 작성되어 있어야 Route 컴포넌트를 사용할 수 있음.index.js import React from 'react'; import ReactDOM from 'react-dom'; import { BrowserRouter } from 'react-router-dom'; ReactDOM.render(<BrowserRouter><App/></BrowserRouter>, document.querySelector('#root'));
Switch, Route
경로를 매칭해주는 역할을 하는 컴포넌트임.
<Switch>
컴포넌트는 여러<Route>
를 감싸서 그 중 경로가 일치하는 단 하나의 라우터만 렌더링을 시켜주는 역할을 함.<Switch>
를 사용하지 않으면 매칭되는 모든 요소를 렌더링함.
<Route>
컴포넌트는 path 속성을 지정하여 해당 path에 어떤 컴포넌트를 보여줄지 정함. Link 컴포넌트가 정해주는 URL 경로와 일치하는 경우에만 작동됨.
Link
경로를 연결해주는 역할을 하는 컴포넌트임. 페이지를 새로 불러오지 않고
HTML5 History API
를 이용해 페이지의 주소만 변경해 줌.ReactDOM으로 렌더링 하면
<Link>
컴포넌트는<a>
태그로 바뀜.React Router 에서
<a>
태그가 아닌<Link>
를 사용하는 이유는?
<a>
태그는 페이지를 전환하는 과정에서 새로고침 현상이 일어나게 됨.
하지만<Link>
컴포넌트는 페이지 전환을 방지하는 기능이 내장되어있기 때문에 SPA를 구현할 수 있음.function App() { return ( <BrowserRouter> <div> <nav> <ul> <li> <Link to="/">Home</Link> </li> <li> <Link to="/mypage">MyPage</Link> </li> <li> <Link to="/dashboard">Dashboard</Link> </li> </ul> </nav> <Switch> <Route exact path="/"> <Home /> </Route> <Route path="/mypage"> <MyPage /> </Route> <Route path="/dashboard"> <Dashboard /> </Route> </Switch> </div> </BrowserRouter> ); } export default App;
exact
란?<Route>
컴포넌트를 모두 보여줌. exact는 주어진 경로와 정확히 일치해야만 설정한 <Route>
컴포넌트를 보여주는 역할을 함.exact
속성을 쓰지 않고도 페이지를 전환하려면?<Switch>
를 사용하여 exact 역할을 대신 해주는 경우임. 하지만 <Switch>
는 순서와 위치가 중요함. 위에서 아래로 경로를 하나씩 검사하면서 해당 경로에 해당하는 라우트를 실행시키기 때문임. 이런 경우, 비교할 라우트(/ 와 비교할 라우트 /mypage, /dashboard)를 더 상단에 작성해야 함. <Switch>
<Route path="/mypage">
<MyPage />
</Route>
<Route path="/dashboard">
<Dashboard />
</Route>
<Route path="/">
<Home />
</Route>
</Switch>
하지만 만약 Home을 위에 둔 상태에서 exact
없이 활용한다면 중복되는 경로(/)로 인해 다른 라우트로의 이동이 불가능함. (즉, Link의 /mypage, /dashboard도 Route의 /에서 걸러짐.) 이를 방지하기 위해 exact
를 사용하는 거임.
참고로, Link에서도 exact를 사용할 수 있음.
<Link exact to="/">
또는 <Link to="/" exact="true">
*exact={true}
도 가능.
<NavLink>
를 사용한다면 이를 통해 중복경로를 피할 수 있음.