25일차가 된 시점부터 HA를 보기 전까지 React
에 대해서 배우고 실습을 진행했다. 전에는 DOM
을 통해서 javacript
로 html
을 조작했지만, React
를 통해서는 약간 이 두가지가 혼합된 형태로 사용할 수 있었다. 부트캠프를 하면서 한 unit을 이렇게 오래한 건 처음이다 보니까 정리하는데에 꽤 시간도 걸릴 것 같다. 슬슬 정리를 시작해보겠다.
React
는 프론트엔드 Javascript 오픈소스 라이브러리다. 그리고 중요한 것은 개발을 컴포넌트 단위로 나누어 생각하고 한다는 것이다. 컴포넌트라고 하면 거의 부품이라고 생각하면 될 것이고 하나의 기능을 하는 작은 부품들이 이루어져 한 product가 만들어진다고 생각하면 편할 것이다.
html, css, javascript
로 나눠서 적기보다는 하나의 파일에 명시적으로 작성할 수 있게 JSX
를 활용한 선언형 프로그래밍을 지향한다.javascript
프로젝트 어디에든 유연하게 적용될 수 있다.이는 문자열도 아니고, html
도 아닌 React
에서 UI를 구성할 때 사용하는 문법으로 javascript를 확장한 문법이다. jsx를 통해서 React 엘리먼트를 만들 수 있다.
Babel
JSX
는 브라우저가 바로 실행할 수 있는 javascript
코드가 아니다. 그래서 브라우저가 이해할 수 있는 javascript
코드로 변환하기 위해 Babel을 이용한다.
Babel은 JSX를 브라우저가 이해할 수 있는 javascript로 컴파일한다.
React에서는 DOM
과 다르게 CSS
, JSX
문법만을 가지고 웹 앱 개발이 가능하다.
JSX
를 사용하면 javascript
만으로 마크업 형태의 코드를 작성하여 DOM
에 배치할 수 있다.
중요한건!! html
처럼 생겼지만 html
이 아니기 때문에 babel을 통해서 컴파일을 하는 것이다.
JSX
를 쓰는 이유는 한 눈에 볼 수 있는 기능과 디자인을 가졌으며, 이를 사용하면 복잡성이 줄고, 가독성은 증가한다 . 반대로 React를 사용하지 않으면 복잡성이 증가하고, 가독성이 줄 수도 있다.
하나의 엘리먼트 안에 모든 엘리먼트가 포함되어야 한다.
<div>jogiyo</div> <div>hi</div> // X ---- <div> <div>jogiyo</div> <div>hi</div> </div> // O
엘리먼트 클래스 사용시 class = '~~~'
가 아닌 className = '~~~'
으로 사용해야 한다.
<div className = "name">jogiyo</div>
Javascript 표현식 사용 시, 중괄호를 사용해야한다. 그렇지 않으면 일반 텍스트로 인식한다.
function App() { const name = 'jogi' return ( <div> Hi, {name}</div> // <-- 이 부분처럼 사용해야 한다. ) }
사용자 정의 컴포넌트, js파일에선 function으로 선언한 부분이라 생각하면 될 것이다. 이는 대문자로 시작한다. 소문자는 일반적은 html
엘리먼트로 인식할 수 있다.
조건부 렌더링을 해야한다면 삼항 연사자를 사용한다.
<div> (조건문) ? (<p>True!</p>) : (<p>False!</p>) </div>
여러 개의 HTML 엘리먼트를 표시할 때는, map()
함수를 이용한다.
map()
함수를 사용할 때는 "key" JSX 속성을 넣어야 한다. 그렇지 않으면 경고가 표시된다.const content = msgs.map((msg) => <div key = {msg.id}>~~~</div>)
정의
컴포넌트를 여러개 만들고 조합을 하면 어플리케이션을 만들 수 있다.
리액트 어플리케이션은 컴포넌트들의 관계를 트리구조로 형상화하여 표현할 수 있다.
화면의 구조를 바꾸는 것과 같은 작업을 할 때, 리액트를 이용하면 변경하려는 UI에 맞춰 컴포넌트의 위치만 바꾸면 되기 때문에 전체를 뜯어 고치지 않아도 된다.
서버로부터 완전히 새로운 페이지를 불러오지 않고 페이지 갱신에 필요한 데이터만 받아 그 정보를 기준으로 현재의 페이지를 업데이트 함으로써 사용자와 소통하는 웹 어플리케이션이나 웹사이트이다.
쉽게 유튜브를 생각해도 되겠다.
전체 페이지가 아니라 필요한 부분의 데이터만 받아서 화면을 업데이트하면 되기 때문에 사용자와의 상호작용에 빠르게 반응한다.
서버에서는 요청받은 데이터만 넘겨주면 되기 때문에 서버 과부하가 문제가 현저하게 줄었다.
전체 페이지를 렌더링 할 필요가 없기 때문에 더 나은 유저경험(UX)을 제공한다.
SPA의 경우 js 파일의 크기가 다르다. 이 때문에 js 파일을 기다리는 시간으로 인해 첫화면 로딩시간이 길어진다.
검색 엔진 최적화(SEO)가 좋지 않다. 하지만 SPA에서도 검색엔진 최적화에 대응할 수 있도록 검색엔진이 발전하고 있어, 이 단점은 완화되고 있는 추세다.
우선은 react router를 이용한 react spa 개발 방법을 학습할 수 있었다. 생각보다 꽤 편하게 사용할 수 있는 기능인 것 같다.
SPA는 하나의 페이지를 가지고 있지만 사실 한 종류의 화면만 사용하지는 않는다. 또한 화면에 따라 주소도 달라지는 것을 알 수 있을 것이다.
라우팅 : 다른 주소에 따라 다른 뷰를 보여주는 과정을 "경로에 따라 변경한다"라는 의미다.
React 자체에는 이 기능이 내장되어 있지 않아 React Router라는 라이브러리를 사용한다.
주요 컴포넌트를 사용하기 위해서는 아래와 같이 가져와야 한다.
import {BrowserRouter, Switch, Route, Link} from "react-router-dom";
<
BroweserRouter>
: Router 역할웹 애플리케이션에서 HTML5
의 History API
를 사용해 페이지를 새로고침하지 않아도 주소를 변경할 수 있는 역할이다.
이것이 상위에 작성돼 있어야 Route
컴포넌트를 사용할 수 있다.
<
Switch>
, <
Route>
: 경로를 매칭해주는 역할<Switch>
는 여러 <Route>
를 감싸서 그 중 경로가 일치하는 단 하나의 라우터만 렌더링을 시켜주는 역할이다. 이를 사용하지 않으면 매칭되는 모든 요소를 렌더링한다.
<Route>
는 path 속성을 지정하여 해당 path에 어떤 컴포넌트를 보여줄기 정한다. Link 컴포넌트가 정해주는 URL과 일치하는 경우에만 작동된다. Route컴포넌트에서 쓸 수 있는 exact라는 속성은 주어진 경로와 정확히 일치해야 설정한 <Route>
컴포넌트만 보여준다.
<
Link>
: 경로를 연결해주는 역할페이지 전환을 통해 페이지를 새로 불러오지 않고 애플리케이션을 그대로 유지하여 HTML5의 History API를 이용해 페이지의 주소만 변경한다.
React Router에서 <a>
가 아닌 <Link>
컴포넌트를 사용하는 이유는 페이지 전환을 방지하는 기능이 내장되어 있기 때문이다.
아래는 이들을 적용한 코드이다.
애플리케이션의 상태
컴포넌트 내에서 변할 수 있는 값, 즉 상태는 React State로 다루어야 한다.
State hook, useState
useState 사용법
- 먼저 아래와 같이 상단에서 import를 해준다.
import {useState} from "react";
useState를 호줄하면 배열을 반환하는데, 배열의 0번째 요소는 현재 state변수, 1번째 변수는 이 변수를 갱신할 수 있는 함수이다. 그리고 useState의 초기값으로 넘겨주는 값은 state의 초기값이다.
const [state저장변수, state갱신함수] = useState(state초기값);
react state는 state갱신함수
호출을 통해 변경해야 한다.
그리고 중요한 것은 state갱신함수
를 통해 state가 변화하면 화면은 다시 렌더링된다.
컴포넌트의 속성(property) 을 의미한다
변하지 않는 외부로부터 전달받은 값으로, 웹 애플리케이션에서 해당 컴포넌트가 가진 속성에 해당한다.
부모(상위) 컴포넌트로부터 전달받은 값 -> Props를 함수의 전달인자처럼 전달 받는다.
객체 형태이다. Props로 어떤 타입의 값도 넣어 전달할 수 있도록 Props는 객체의 형태를 갖는다.
Props는 읽기전용이다. 함부로 변경될 수 없는 읽기 전용 객체이므로, 함부로 변경되서는 안된다.
DOM
과 비슷하지만 문법차이가 있다.JSX
를 사용해 문자열이 아닌 함수로 이벤트 처리 함수를 전달한다.// DOM onclick = "handleEvent()" // React : event 객체의 속성을 이용할 때 onClick = {handleEvent} // React : event 객체가 아닌 밖의 다른 요소를 파라미터로 사용하고 싶을 때 onClick = () => {handleEvent(parameter)}
중요한 것은 컴포넌트로 생각하는 것이다. React 개발 방식은 페이지 단위가 아닌 컴포넌트 단위로 시작한다.
데이터는 위에서 아래로 흐른다.(하향식 흐름)
두 개의 서로 다른 컴포넌트가 특정 상태에 의존적인 경우, 공동 소유 컴포넌트(공통의 부모)를 쫓아 그 곳에 상태를 위치하여야 한다.
실습은 페어프로그래밍으로 진행됐으며 5일정도 같은 유닛을 함께 했다. 3가지의 실습이 있었다. React 기초, SPA & Router, State & Props 세 가지 실습 모두 여태 해왔던 실습들에 비해 꽤 난이도가 있었다. 튜터분들께서는 아직 적응하지 못해 어려울 수 있다고 말씀을 해주셨는데 확실히 그 말이 맞는것같으면서도 아직 부족하다보니 어려웠던 것 같다. 이 세 가지를 진행하면서 이건 꼭 알아야겠다 싶었던 것이 Router와 State & Props였다. Router는 생각보다 사용에 적응하는데에는 어려움이 없었는데 State & Props를 사용하고 이해하는데에는 어려움이 있었던 것 같다. 그래도 여기에서도 꽤 큰 수확이 있었다. State가 바뀌기 위해서는 State갱신함수를 통해 바꿔줘야 하며 이 함수를 사용하면 화면이 다시 렌더링된다. 이 것을 내가 생각못하고 계속 진행을 했는데 과제를 푸는데 있어서 어려움을 겪었던 것 같다. 그리고 아직은 props를 전달해주는 것이 익숙치 않은데 이를 좀 더 익혀야 할 것 같다. 이렇게 5주간의 Section 1의 모든 유닛들을 끝마쳤다. 분명 쉬운 부분도 있었고 어려운 부분도 많았다. 그리고 생각보다는 내가 얻어가는게 많은 것 같아 헛된 시간을 보냈다는 생각이 들지는 않아 다행이다. 앞으로의 17주도 더 힘내보자!!