React :리액트의 특징들 (virtual dom, 선언형, 단방향 데이터 바인딩, 컴포넌트, jsx)
리액트란?
React는 웹/앱(RN)의 UI를 개발할 수 있도록 하는 자바스크립트 라이브러리이다.
리액트는 Web이 App처럼 구동할 수 있게 한다.
리액트를 통해 만들어진 웹사이트는 뛰어난 UX를 통해 보통의 웹사이트보다 비즈니스적 강점이 있다.
가장 많이 사용하는 자바스크립트 라이브러리이고, 가장 만족도가 높은 자바스크립트 라이브러리이다.
타입스크립트와 설치.
yarn create react-app . --template typescript // 생성 폴더 자리에 “ . “ 을 찍으면 현재 폴더에 생성된다.
기억해야하는 키워드
프레임워크vs라이브러리,
SPA,
CSR,
Virtual Dom,
컴포넌트. 독립적이고 재사용이 가능한.
리액트는 라이브러리로서 프레임워크인 앵귤러, 뷰와 비교할 수 있다.
앵귤러는 프레임워크이다. 프레임워크는 뭔가를 만드는데 필요한 모든게 준비되어 있다. 예컨데 UI, Routing, http clients 통신과 같은 기능을 위한 틀이 정해져있고 그 틀 안에서 만들어야 한다. 자율성이 떨어지고, 다 배워야 사용할 수 있기 때문에 진입벽이 높다고 할 수 있다. (IOS / Andriod 도 프레임워크의 일종)
리액트는 라이브러리이다. 라이브러리는 모든 것이 아닌 일부분을 위한 것이다. 리액트는 UI를 위한 라이브러리이다. 그렇기 때문에 사이트 구성을 위해 다른 라이브러리들이 또 필요하다. 필요할 때마다 내가 원하는 것들을 사용할 수 있는 자율성이 있다.
뷰는 프레임워크 같지만 state management, http clients를 지원하지 않는다는 점에서 그 중간지점에 있다고 할 수 있다.
리액트의 특징들
1. Virtual DOM (가상 돔)
입력 등 과 같은 이벤트를 통해 화면에 변화가 생기면, 브라우저에서는 DOM 조작을 통해서 레이아웃 과정을 다시 진행되게 된다.
이 과정을 리플로우(Reflow)라고 하며, 페인팅 과정이 다시 진행되는 것을 리페인트(Repaint)라고 한다.
리플로우와 리페인트는 DOM의 각 노드에 대한 연산 과정을 다시 수행하기 때문에 많이 수행 될수록 웹 서비스의 성능이 저하된다.
리액트는 리플로우와 리페인트가 자주 수행되는 문제를 해결하기 위해 화면에 표시되는 DOM과 동일한 가상 DOM을 메모리상에 만들고 DOM 조작이 발생하면 가상 돔에서 모든 연산을 수행한 뒤에, 그 다음 실제 DOM을 갱신해서 리플로우/리페인트 연산을 최소화 한다.
리액트는 두개의 가상 돔 객체를 가지고 있다. 렌더링 이전의 화면구조를 담은 객체와, 렌더링 이후에 보이게 될 화면구조를 담은 객체.
이 두가지 객체는 자바스크립트 객체형태로 메모리에 저장된다.
리액트는 어떤 변화가 일어났을 때 실제 브라우저에 그려지기 전, 렌더링 이후에 보이게 될 화면구조의 가상돔과, 렌더링 이전의 화면구조를 담은 가상돔을 비교하여(Diffing),
변화가 필요한 부분만 실제 브라우저 화면에 적용시켜 준다.(Reconciliation)
이 때도 바뀐 부분들을 하나 하나 변화시켜 주는 것이 아니라, 한번에 'Batch Update' 한다. 집단으로 적용시켜 주는 것.
변경된 내용을 하나하나 따로 반복해서 그려주는게 아니라 변화된 부분을 한번에 받아와서 한번에 그려 주는 것.
1. state change. 뭔가 바뀌었다. 전체 UI는 Virtual DOM에 렌더링 된다.
(Virtual DOM은 HTML DOM의 추상화 버전입니다. 실제 DOM object와 같은 속성들을 가지고 있지만, 실제 DOM이 갖고 있는 api는 갖고 있지 않다.)
2. 변화 전의 가상돔과 변화 후의 가상돔을 비교한다.
3. 비교 완료 후 바뀐 부분만 실제 DOM에 적용한다. 필요한 부분만 변경해 준다는게 key point다.
(바뀐 부분만 실제 돔에 적용을 함으로서 레이아웃 계산은 한 번만 이행한다.)
--
추가로 예를 들어 todo 리스트에 할 일을 하나 추가 했고 '새로운 할 일의 표시' 와 '총 할 일의 개수 증가' 두가지 변화가 일어 나야 한다고 했을 때,
자바스크립트에서는 새로운 할 일의 표시에 대한 리플로우/리페인트가 한 번 발생하고,
전체 할 일 개수를 표시하기 위해 리플로우/리페인트가 또 한번 발생하게 된다.
하지만 가상 돔을 통한다면,
사용자가 할 일을 입력하고 추가 버튼을 눌렀을 때,
'새로운 할 일의 표시', '총 할 일의 개수 증가'를 가상 돔에서 같이 계산해서 브라우저에 전달함으로서 리플로우/리페인트를 한 번만 수행하도록 하게 할 수 있는 것.
이렇게 리액트에서는 가상 돔을 사용하여 DOM이 자주 갱신되는 싱글 페이지 애플리케이션의 리플로우와 리페인트를 최소화함으로써 성능을 최적화시켰다.
2. 선언형
선언형 코드들은 무엇을 할 것인가. 명령형(절차형) 코드들은 어떻게 할 것인가.
선언형 프로그래밍은 최종적인 목표가 무엇인지가 중요하다. 목표를 이루기 위한 세부적인 단계에는 관심이 없다.
이와 비교되는 것이 명령형(절차형). 명령형은 우리가 원하는 기능을 수행하기 위한 단계들을 명시적으로 나열한다.
코드예시
- 숫자 배열을 받아서, 해당 배열의 모든 원소들을 두 배 시킨 새로운 배열을 리턴하는 'double'이라는 이름의 함수를 작성하세요.
ex) double([1, 2, 3]) // [2, 4, 6]
명령형 (절차형)
function double (arr) {
let results = []
for (let i = 0; i < arr.length; i++){
results.push(arr[i] * 2)
}
return results
}
선언형
function double (arr) {
return arr.map((item) => item * 2)
}
명령형에서는 'results'라는 변수를 만들어 그것을 계속해서 수정하고 있다. 답을 찾기 위한 단계들을 명시적으로 나열한다.
선언형에서는 어떻게 처리할지보다, 무엇을 원하는지를 설명한다. 해당 함수를 통해 map 이라는 메소드가 어떤 과정을 통해 답을 찾아나가는지 알 수 없다. 과정들은 map이라는 메소드 내부에 추상화 되어있다.
많은 선언적(Declarative) 접근 방식들의 기반에는 일종의 '명령적(Imperative) 추상화'가 존재합니다.
리액트는 jsx 문법을 통해 구현되지만 jsx를 얻기 위한 알고리즘에 대한 구현은 하지 않는다. 예를 들어, document.createElement 같은 알고리즘, 리-렌더링 여부에 대한 알고리즘을 구현하지 않는다. 이와 같은 특성은, 리액트를 사용할 때 화면 설계라는 초점에 맞춰서 개발할 수 있도록 해주고, 다른 부분에 대한 고민을 최소화 해주어 높은 생산성을 보장할 수 있도록 해준다.
3. 단방향 데이터 바인딩
화면에 표시되는 곳 (View)과 코드를 작성하는 곳 (Model) 이 있다면,
단방향 데이터 바인딩은 코드를 작성함으로써 그 코드가 뷰에 나타나게 하는 하나의 방향으로 데이터가 바인딩 되는 형식이다.
(양 방향의 경우, View에서 사용자가 특정 데이터를 변경시키면 JS에서의 데이터도 변경이 되고, 반대로 JS에서 어떤 값을 수정해도 그 값이 바인딩 되어있는 HTML 요소가 그 값에 따라 자동으로 렌더링 된다.)
단방향 데이터 바인딩에서 사용자가 UI를 통해 자바스크립트의 데이터를 갱신할 때는 이벤트를 통해 갱신하게 된다. 그러므로 데이터의 변화를 감지해 동작하게 하는 코드를 매번 작성해주어야 한다. 이벤트 함수(onChange, onClick...등)를 일일이 걸어줘야한다는 것.
단방향 바인딩은 번거롭고 코드가 길어질 수 있다는 단점이 있지만, 필요한 곳에서만 사용할 수 있음으로 성능면에서 장점이 있다. 이 점으로 인해 데이터 추적과 디버깅도 상대적으로 쉽다.
4. 컴포넌트 기반으로 재사용성이 뛰어나다.
리액트로 웹 서비스를 개발할 때, 컴포넌트라고 부르는 작고 고립된 코드를 사용하여 UI를 구성하게 된다. 이렇게 작고 고립된 컴포넌트는 재사용을 할 수 있으며 이런 재사용을 통해 개발 생산성을 향상시킬 수 있다. 또한 테스트하기도 쉬워 코드를 유지 보수하는데도 도움이 된다.
5. JSX
JSX는 자바스크립트와 HTML을 동시에 사용하며, HTML에 자바스크립트의 변수들을 바로 사용할 수 있는 일종의 템플릿 언어이다.
함수 안에서 자바스크립트 변수를 선언한 뒤 HTML 태그안에서 바로 호출하여 사용할 수 있다. 데이터 바인딩이 쉬워진다.
const Reply = () => {
const hello = "hello"
return (
<h1>{hello}</h1>
)
* 단점 ? Problems with SEO
React에는 하나의 HTML 파일이 있고, 랜더링 되기 이전에는 빈 상태의 HTML만 있게 된다.
SPA(Single Page Application) 웹 앱을 만들기 위한 라이브러리이기 때문에, 검색 엔진 최적화(SEO : search engine optimization) 에 어려움이 있다. 그리하여 React로 만든 웹 사이트는 non-SEO friendly sites 라고 불리기도 한다.
이 단점을 해결 할 수 있는 여러가지 방법이 존재하는데, SSR(Server Side Rendering), meta-tag, Pre-Rendering 등이 있다.
추가로 리액트는 페이지 전환 기능을 제공하지 않기 때문에, 리액트를 사용하여 페이지 전환을 해야한다면, react-router와 같은 추가적인 라이브러리를 사용해야 한다.
참고사이트
https://dev-yakuza.posstree.com/ko/react/create-react-app/react/