2021. 8. 15. 01:17ㆍWEB/React
추가 공부가 필요한 키워드
XML, 번들링, 바벨, 크로스 브라우징, 트랜스파일러
React는 문자열도, HTML도 아닌 JSX라는 JS의 확장 문법을 사용한다
const element = <h1>Hello, React!</h1>;
이때 React Element는 Browser DOM Element와는 달리 일반 객체(plain object)로
쉽게 생성할 수 있다
JSX는 자바스크립트의 확장 문법이다. XML과 매우 비슷하게 생겼으며,
이런 형식으로 작성한 코드는 브라우저에서 실행되기 전에 코드가 번들링되는 과정에서
바벨을 사용하여 일반 자바스크립트 형태의 코드로 변환된다
위 코드는 JSX로 작성된 코드로, 번들링 과정에서 어떻게 JS 형태로 변환되는지 확인해보자
funtion App() {
return React.createElement("div", null, React.createElement("b", null, "Hello, React !"));
}
컴포넌트를 렌더링할 때마다 JSX 코드를 작성하는 것이 아니라
위와 같은 React.createElement 함수를 사용한다면 굉장히 불편할 것이다
(이러한 점 때문에 JSX를 사용하면 UI를 편하게 렌더링할 수 있는 것이다)
번들링?
여러 파일을 하나로 묶어주는 과정, 대표적으로 웹팩(Webpack)이 사용된다
(웹팩은 React의 JSX도 변환작업을 지원한다)
바벨?
먼저 바벨의 개념을 알기 위해서는 크로스 브라우징에 대해 알아야 한다
위 크로스 브라우징의 이슈를 해결하기 위해 생겨난 것이 바벨이다
바벨은 추상화 수준을 유지한 채로 코드를 변화시키는 트랜스파일러(Transpiler)의 역할을 한다
JSX는 React Element를 생성하며, DOM에 렌더링 작업을 처리한다
JSX ?
React는 본질적으로 렌더링 로직이 UI로직과 연결된다
(이벤트가 처리되는 방식, 시간에 따른 state의 변화 방식, 화면에 표시를 위한 데이터 준비 방식 등)
컴포넌트라는 마크업과 로직을 연결한 하나의 요소를 사용한다
JSX의 사용이 필수는 아니지만, JS 코드 안에서 UI 관련 작업진행 시 시각적으로 더 큰 도움을 준다
또한 개발진행 시 에러 및 경고 메시지를 표시할 수 있게 해주어 도움을 준다
* JSX는 리액트 프로젝트를 개발할 때 사용되는 것이며, 자바스크립트 문법은 아니다
JSX의 장점
자바스크립트와 JSX의 코드를 비교해보면 금방 알 수 있다
가독성이 훨씬 뛰어나며 작성방법도 더 쉽다는 것을 금방 느낄 수 있다
주된 장점은 이러한 부분이다, 자바스크립트로 모든 DOM Element에 일일히 접근하게끔
만들어야 한다면 깊게 생각해보지 않아도 불편하고 어려운 작업일 것 같다
이 외에도 JSX의 높은 활용도가 있다
(유사)HTML 태그를 사용할 수 있고, 컴포넌트 또한 JSX 안에서 생성이 가능하다
생성한 컴포넌트 또한 HTML 태그를 사용하듯 동일한 방법으로 사용할 수 있다
해당 코드는 리액트 설치시 설치되는 src/index.js 파일의 코드다
<React.StrictMode />, <App /> 태그들이 모두 직접 생성한 컴포넌트들이다
ReactDOM.render
컴포넌트를 페이지에 렌더링하는 역할을 하며, react-dom 모듈을 불러와 사용할 수 있다
첫 번째 파라미터로는 페이지에 렌더링할 내용을 JSX 형태로 작성한다
두 번째 파라미터로는 해당 JSX를 렌더링할 document 내부 요소를 설정
해당 코드에서는 Id가 root인 요소 안에 렌더링 되도록 설정되있는데,
해당 요소는 public/index.html로 가면 확인할 수 있다
React.StrictMode
리액트의 레거시 기능들을 사용하지 못하게 하는 기능
현재는 사용은 되지만 이후에는 완전히 사라지게 될 옛 기능들의 사용에 대한 경고를 출력한다
JSX의 특징과 HTML의 차이점
1. HTML 태그 내에서 JS 연산처리가 가능하다
<div>
<p id="first"></p> +
<p id="second"></p> =
<p id="sum"></p>
</div>
<script>
const a = 1;
const b = 2;
document.getElementById("first").innerHTML = first
document.getElementById("second").innerHTML = second
document.getElementById("sum").innerHTML = first + second
</script>
위 코드는 HTML에서의 JS 연산처리
const plus = () => {
const a;
const b;
return <div>{a} + {b} = {a + b}<div>
}
위 코드는 JSX에서의 JS 연산처리, 가독성이나 생산성 측면에서 높은 효율을 보인다
2. HTML의 class는 className으로 표현한다
<div className="style">
Hello, React
</div
위와 같이 HTML attribute인 class는 JSX에서 className으로 표현한다
3. 스타일 적용시 string이 아닌, object로 적용한다
<div style={{ backgroudColor: "black", color: "white" }}>
글자, 배경색 변경
</div>
스타일 지정시 {{ }} template 언어와 같은 형태로 작성한다
바깥쪽 중괄호는 JS를 사용함을 나타내며, 안쪽 중괄호는 JS에서의 object 사용을 의미
이때 Inline style의 Property name은 camelCase의 형태로 작성한다
예) background-color → backgroundColor, font-size → fontSize 등
(낙타의 등과 같은 형태를 보이기 때문에 부르게 된 명칭, 위 className 또한 같은 형태로 작성)
4. HTML에서는 input, image 등은 닫는 태그를 사용하지 않지만, JSX는 닫는 태그가 필수적이다
<div>
안녕하세요 </br>
반갑습니다
</div>
br 태그와 같이 기존의 닫는 태그가 필요없던 태그들도 JSX에서는 필수적으로 작성한다
예) image, input, br 등
5. 최상단에는 반드시 하나의 엘레먼트(Element)만 위치해야 한다
const test = () => {
return (
<div>
<p></p>
</div>
)
}
위와 같이 최상단에는 반드시 하나의 엘레먼트만 작성되어야 한다
아래와 같이 작성시 에러 발생
const test = () => {
return (
<div></div>
<div></div>
)
}
최상단 Element는 div 또는 React.Fragment를 이용해서 감싸준다
(실제 렌더링 시 div 또는 Fragment 안에 있는 내용만 화면에 출력되어진다)
<React.Fragment>
</React.Fragment>
<> </> ← Fragment의 축약형이라고 할 수 있다
DOM
Document Object Model의 약자, 웹 페이지에 대한 인터페이스다인터페이스이기 때문에
DOM을 통해 구조, 컨텐츠, 스타일과 같은 정보를 읽고 조작할 수 있다
잠시 Web page가 빌드되는 과정을 살펴보자
1. 브라우저가 HTML과 CSS를 파싱하며 화면에 어떤 데이터를 출력할지 결정
2. DOM
3. CSSOM
4. render tree
5. 브라우저가 rendering을 진행
6. JS 실행
7. async, defer
예외적으로 리플로우와 리페인트가 있다
여기서 파싱이란 HTML, CSS 등에서 원하는 데이터를 특정한 패턴 또는 순서(token)로 추출한 후
원하는 형태로 조힙해서 파스 트리(parse tree)를 만드는 과정을 말한다
* token : 어휘 분석의 최소 단위
1번 ~ 3번 과정을 완료하면 렌더트리가 만들어진다
렌더트리는 화면에 출력되는HTML Element와 대응된 CSS 스타일을 표현한 것이다
이러한 렌더트리를 만들기 위해서는 CSSOM(CSS Object Model)과 DOM이 필요하다
DOM은 HTML 문서를 객체 기반으로 표현한 것이다
객체 기반으로 표현한 이유는 다양한 프로그램에서 구조와 내용을 객체 모델로 변경한 후
쉽게 사용할 수 있게 하기 위함이다
이러한 DOM의 객체 구조는 노드 트리라고도 표현한다(루트(root) 노드에서부터 가지를 치며,
리프(leaf) 노드들이 뻗어나가는 형태 때문) 가장 밑단의 리프 노드에는 각 Element와 content가 위치한다
* 이때의 루트 노드는 리액트와 마찬가지로 반드시 하나만 위치할 수 있다
DOM은 HTML 문서로부터 생성되긴 했지만, 그렇다고해서 같은 것은 아니다
첫 째, DOM은 어디까지나 유효한 HTML 문서에 대한 인터페이스다
HTML을 파싱, DOM Tree를 생성하는 과정에서 문제가 있는 HTML의 수정이 가능하다
가령 누락된 Element가 있어 유효하지 못한 HTML이 된 상태에서,
DOM은 자동으로 누락된 Element를 추가하는 등의 수정 작업이 가능하다
둘 째, JS에 의한 수정이 발생한 경우 DOM은 더 이상 정적이지 않게 된다
DOM에 접근하여 자유로운 추가, 수정 작업을 통해 동적인 상태가 되었다고 가정하자
그렇다고한들 원본의 HTML의 Element에 변화가 발생하진 않는다
출력된 화면은 HTML이 아니다?
위 사항을 기반으로 생각해보았을 때 분명하게 알 수 있는 점은 출력 부분에 있다
브라우저 상에 출력이 되는 것은 HTML도 DOM도 아닌, 렌더트리다
처음 렌더트리가 생성되는 과정에서 간단히 알아본 바와 같이 렌더트리는 오로지
어떤 부분이 화면에 렌더링 되어야할 부분인지만 관심이 있는 상태다
즉, 화면에 출력되지 않는 부분은 애초에 렌더트리에서 제외됨을 의미한다
예로 display: none과 같은 Element는 DOM에 있지만 레이아웃 자체에 영향을 주지 않는,
화면에 출력되지 않는 부분이기 때문에 렌더트리에서는 제외되게 된다
반대로 visibility: hidden와 같이 display:none과 마찬가지로 화면에서는 사라지지만,
그 자체로 레이아웃에 영향을 주는 출력 부분이기 때문에 렌더 트리에 포함된다
DOM Node와 DOM Element의 차이
DOM Node은 위에서 살펴본 바와 같이 Node tree의 형태로 구성되어 있다
(각 노드들은 서로 부모 ↔ 자식 관계, 형제 ↔ 자매 관계로 연결되어지게 된다)
html
-head
--title
--meta
--link
-body
--header
---nav
---div
--main
--footer
---"text"
--script
포인트는 HTML의 태그 뿐 아닌, 태그 안에 속한 텍스트 노드도 모두 DOM 노드에 포함된다
Node tree의 계층적 구조 형태 그대로 DOM을 객체 형태로 나타낼 수 있다
{
document: {
html: {
head: {
title: ...
},
body: {
...
}
}
}
}
DOM을 제어해서 document의 자식 객체에 접근할 때는 html 태그를 건너띄게 된다
document.head ~, document.body ~ 와 같은 형태로 자식 노드(객체)에 접근할 수 있다
만약, <title>에 접근하고 싶다면 document.head.children[0]과 같은 형태로 사용할 수 있다
(getElementByTagName("title") 또한 접근 가능하다)
children : 텍스트 노드 제외
childNodes : 텍스트 노드 포함
DOM Element는 텍스트 노드를 제외한, 흔히 생각하는 <> 형태의 태그만을 의미한다
이 때문에 DOM을 제어해서 태그를 검색할 때는 Element가 붙은 method를 사용하는 것이다
예) getElementByTagName(' ')
이러한 이유로 주석, text node와 같은 것들은 Element가 아니다
JS DOM에서 Node는 node의 생성자(constructor), HTMLElement는 element의 생성자다
DOM Property
Node와 Element 각각의 DOM Property를 구분하는 것이 중요하다
* 여기서 프로퍼티(Property)란, DOM의 속성을 말한다
(Attribute는 HTML 태그의 속성으로 둘은 다르다)
Node의 프로퍼티는 node 또는 NodeList라고 하며,
Element의 프로퍼티는 element 또는 HTMLCollection이라고 한다
둘 다 Node의 children을 가져오는 프로퍼티라는 점은 동일하나, 분명한 차이가 있다
<div>
<h2>Hello, DOM</h2> Welcome to the world
</div>
위와 같은 Node tree가 있을 때, 둘의 차이를 명확히 파악할 수 있다
(이 부분은 제대로 해결이 안되서 추후 내용 추가 .. 가장 중요한 부분인데 ..)
'WEB > React' 카테고리의 다른 글
13. React (Re: act #2) (0) | 2021.08.18 |
---|---|
12. React (Re: act #1.5) (0) | 2021.08.17 |
10. React (Asynchronous JavaScript) (0) | 2021.08.12 |
9. React (Form 2) (0) | 2021.08.10 |
8. React (Form) (0) | 2021.08.09 |