본문 바로가기

Frontend

[Rising Camp] Frontend, React, API

1. DOM이란?

DOM(Document Object Model)이란 HTML, XML 문서에 접근하기 위한 프로그래밍 인터페이스로 문서 객체 모델이라고 부른다. 구조화된 문서를 표현하며 자바스크립트와 같은 프로그래밍 언어를 통해 웹 문서에 접근 및 제어할 수 있는 방법을 제공하여 웹 문서를 관리하는 역할을 한다. W3C의 표준 객체 모델이며 계층 구조로 표현된다. nodes와 object로 문서를 표현한다.

DOM이란 브라우저에서 다룰 HTML 문서를 객체로 구조화하여 나타낸 문서 객체 모델을 의미한다. DOM은 HTML Elements, Attributes, CSS styles, Events, Methods 등을 제어할 수 있는 표준 인터페이스를 제공한다. 즉, HTML 파일 내용을 토대로 만들어지며 JavaScript를 이용해 동적으로 수정할 수 있다. 변경된 DOM은 렌더링에 반영된다.

웹 문서를 브라우저의 렌더링 엔진에 로드 → 파싱(변환) → 웹 문서를 브라우저가 이해할 수 있는 구조로 구성 → 메모리에 적재

 

DOM은 세 가지 모델로 구분된다.

  1. Core DOM: 모든 문서 타입을 위한 DOM 모델
  2. HTML DOM: HTML 문서를 위한 DOM 모델
  3. XML DOM: XML 문서를 위한 DOM 모델

 

JavaScript는 이러한 객체 모델을 이용하여 다음과 같은 작업을 수행할 수 있다.

  • 새로운 HTML 요소나 속성을 추가
  • 존재하는 HTML 요소나 속성을 제거
  • HTML 문서의 모든 HTML 요소를 변경
  • HTML 문서의 모든 HTML 속성을 변경
  • HTML 문서의 모든 CSS 스타일을 변경
  • HTML 문서에 새로운 HTML 이벤트를 추가
  • HTML 문서의 모든 HTML 이벤트에 반응

HTML DOM은 HTML 문서를 조작하고 접근하는 표준화된 방법을 정의하며 모든 HTML 요소는 HTML DOM을 통해 접근할 수 있다.

 

웹 문서(HTML)를 브라우저에 렌더링하려면 웹 문서를 브라우저가 이해할 수 있는 구조로 메모리에 올려야 한다. HTML이랑 DOM은 다르다. DOM은 브라우저에서 로드되는 것(장소의 개념)이다. 작성된 HTML 문서가 브라우저에 의해 해석되어 실제 문서를 나타내는 노드 트리가 DOM이다.

 

HTML을 작성해도 결과를 보기 위해서는 브라우저가 필요하다. IDE에 작성된 HTML은 단순한 문자열일 뿐이며, 브라우저가 이해하기 위해서는 노드(객체)로 변환해야 한다. 즉 DOM은 HTML과 자바스크립트를 이어주는 공간으로 내가 작성한 HTML을 자바스크립트가 이해할 수 있도록 객체로 변환하는 것이다. DOM은 내가 작성한 HTML로부터 생성되지만 브라우저가 알아서 노드들을 붙여주기도 한다. 그리고 자바스크립트로 인해 새로운 노드를 추가할 수도 있다. 따라서 자바스크립트를 DOM API라고 부르기도 한다.

다음은 가장 일반적인 노드 유형이다.

  • ELEMENT_NODE (<html>, <body>, <a>, <p>, <script>, <style>, <h1>)
  • ATTRIBUTE_NODE (class=”hi”)
  • DOCUMENT_TYPE_NODE (!DOCTYPE html>)

DOM은 프로그래밍 언어는 아니지만 DOM이 없다면 자바스크립트 언어는 웹 페이지 또는 XML 페이지 및 요소들과 관련된 모델이나 개념들에 대한 정보를 갖지 못한다.

DOM은 노드 트리 형태로 부모-자식 관계를 표현한다.

 

브라우저가 HTML을 전달 받으면 이를 변환(파싱)하고 노드들로 이루어진 DOM 트리를 만든다. 그 후 외부 CSS파일과 각 노드들의 inline 스타일을 파싱하여 스타일을 입힌 Render 트리를 만든다. Render트리가 만들어지면 각 노드들이 화면에서 어디에 나타나야 하는지에 대한 위치가 주어지고 paint()메서드 호출을 하면 화면이 출력된다.

 

DOM은 해당 과정을 계속 반복한다. 즉, 오타 수정, 문구 제거 혹은 이미지를 첨부하는 사소한 일을 하더라도 DOM은 처음부터 다시 HTML을 파싱하여 DOM트리를 만들고 CSS를 파싱하여 Render 트리를 만들고 레이아웃을 입혀 출력한다.

겨우 오타 하나를 잡고 싶을 뿐인데 전체 사이트를 다시 처음부터 렌더링해야 하며 해당 오타를 찾기까지 너무 많은 시간이 걸린다는 단점이 있어서 Virtual DOM**이 나오게 되었다.

 

DOM을 사용하는 이유

  • JavaScript를 통해 HTML에서 데이터를 가져오고 싶을 때
  • 웹 페이지 데이터를 동적으로 변경하고 싶을 때

DOM이 HTML, CSS, JavaScript에 접근하는 방법

  • getElementBy(), querySelector() 사용

 

2. HTML 전체적인 구조와 필수 태그

HTML 문서는 <html> 태그로 시작해서 </html> 태그로 끝나며 <head> 태그와 <body> 태그를 가지고 있다. <head> 태그는 문서의 정보를 정의하고 <body> 태그는 사용자가 볼 수 있는 내용을 담고 있다.

 

  1. <title>: 웹 페이지의 제목을 나타내며 <head> 태그 안에 속해있다.
  2. <div>: 특정 영역을 담당하는 태그이다. 문단을 나눌 때 사용한다. 자동 줄 바꿈이 된다.
  3. <button>: 버튼 태그이다.
  4. <a>: 사이트 링크와 관련된 태그이다.
  5. <script>: HTML 문서에서 바로 스크립트를 작성하기 위해 필요한 태그이다.
  6. <link>: CSS 문서의 외부 소스를 연결하는 태그로 <head> 태그 안에 적는다.
  7. <img>: 이미지를 담는 태그이다.
  8. <span>: 웹 페이지의 영역을 설정할 때 사용하는 태그이다. 자동 줄 바꿈이 되지 않는다.
  9. <p>: 문단을 뜻하는 태그이며, 웹 페이지에 일반적인 텍스트를 넣을 때 사용한다.
  10. <li>: 리스트의 내용을 적는 태그이다.
  11. <ul>: <li> 태그를 감싸는 부모 태그이다.
  12. <style>: CSS를 적을 수 있게 하는 태그이다. <head> 태그 안에 적는다.
  13. <h1>~<h6>: 문서 내에 있는 크고 작은 제목을 적는 태그로 <h1>이 가장 큰 단위이다.
  14. <input>: 입력 필드이다.
  15. <nav>: 네비게이션 링크를 담는 태그이다.
  16. <section>: 섹션을 나타내는 요소에는 section, nav, article, aside가 있다.<div> 태그는 단순 블럭 요소를 나타낸다. 반면에 <section> 태그는 제목을 나타내는 <h1>~<h6> 태그를 포함한다.
    <div> 태그와 <section> 태그의 차이점은 섹션(문단, 장, 절)을 나타내는 기능을 한다는 것이다.
  17. <article>: 블로그, 뉴스, 기사 내용, 공지사항 섹션을 나타낼 때 사용한다.
  18. <aside>: 사이드바에 있는 최근 글 목록, 인기 글 목록, 즐겨찾기, 배너 리스트를 나타낼 때 사용한다.
  19. <header>: section 태그의 header을 정의할 때 사용한다. 도입부에 해당하는 콘텐츠나 네비게이션 링크의 정보를 포함한다. header 태그는 여러 개 사용 가능하다.

3. CSS 필수 속성

CSS란 사용자에게 문서를 표시하는 방법을 지정하는 규칙 기반 언어이다. 텍스트 문서 스타일링에 사용된다.

 

  1. width
  2. 가로 길이 속성이다.
  3. height
  4. 세로 길이 속성이다.
  5. margin
  6. 바깥쪽 여백 속성이다.
  7. padding
  8. 안쪽 여백 속성이다.
  9. color
  10. 색상 속성이다.
  11. font
  12. 글꼴 속성이다.
  13. text-align

텍스트 정렬 방향 속성이다.

  1. background
  2. 배경 속성이다.
  3. flex
  4. 1차원으로 수평, 수직 영역 중 하나의 방향으로만 레이아웃을 나눌 수 있다.
  5. grid
  6. 2차원으로 수평, 수직을 동시에 영역 나누기가 가능하다.
  7. ::after주로 content 속성과 사용된다.
  8. 가상 요소 선택자로 홈페이지 헤더나 푸터에 구분선을 삽입할 때 사용한다.

 

[flex]

flex에서 행과 열로 나열하는 방법으로는 flex-direction이 있다.

기본적으로는 row로 형성되어 있으며 flex-direction을 통해서 column으로 바꿀 수 있다.

flex-wrap은 요소가 특정 영역을 벗어난 경우 한 줄에 배치되게 할 것인지 줄바꿈으로 여러 행에 나누어 배치되게 할 것인지를 결정한다. flex-wrap을 nowrap으로 지정하면 한 줄로 표현이 되고 wrap으로 설정하면 container 영역을 벗어났을 경우 줄바꿈으로 처리가 된다.

flex-align은 flex 내부 항목의 열의 정렬을 결정하는 방법으로 기본적으로 stretch로 설정 되어 있다.

[grid]

grid에서는 fr 단위로 비율을 사용할 수 있다. 일반적인 px 단위와는 다르며 행과 열을 가변적으로 조정할 수 있다.

grid의 행과 열은 grid-template-columns와 grid-template-rows으로 정의한다.

 

flex와 grid를 사용하는 때는 다르다.

flex는 콘텐츠 위주의 정렬, grid는 레이아웃 위주의 정렬로 이루어진다.

flex 레이아웃은 flex container 안에 있는 flex item을 중앙 정렬이나 균등하게 설정하기에 좋으며 복잡한 레이아웃도 적은 코드로 간결하게 설정이 가능하다.

grid 레이아웃은 카드 형식으로 되어있는 신문 형식의 레이아웃을 쉽게 만들 수 있고 여백을 쉽게 조절할 수 있다.

 

  • 선택자 우선 순위
    1. !important: 속성 값 바로 뒤에 넣는다. (우선순위 1순위)
    2. inline style: tag 내에 style을 정의한 것이다.
    3. id Selector: tag 내에 id를 정의한 후 #id로 선택한다.
    4. class Selector: tag 내에 class를 정의한 후 .class로 선택한다.
    5. tag Selector: tag 요소를 선택자로 사용한다.
    6. universal Selector: asterisk(*)으로 요소 전체를 선택한다.

id > class

class > 요소

요소 > 전체

특정 요소의 class 선택자 > class 선택자

 

4. JavaScript

  • 변수 선언: 별도의 키워드 없이 변수를 할당하는 암시적 선언이 있다. 일관된 키워드인 var을 작성하여 변수를 선언한다. 이를 동적 바인딩이라고 한다.
  • 자료형: 숫자형, 불린형, 문자형, 심볼형, null, undefined이 있다.
  • 반복문: for 반복문, for-in 반복문이 있다. for-in 반복문은 in 키워드를 사이에 두고 오른쪽에는 반복할 대상 변수를, 왼쪽에는 속성명을 작성한다.
  • 연산자: 동등 연산자 (==)와 일치 연산자 (===)가 있다. 동등 연산자는 값의 자료형과 상관없이 내용이 같으면 true를 반환하고 일치 연산자는 값뿐만 아니라 자료형까지 일치하는지 비교한다.
  • 이벤트 리스너: DOM 객체에서 이벤트가 발생한 경우 해당 이벤트 처리를 담당하는 함수를 가리킨다. 이벤트 핸들러라고도 한다. Inline, Property Listener, AddEventListener를 사용해서 등록 방법을 제공한다.
  • 디버깅: console.log와 개발자 도구(f12)를 통해서 디버깅을 할 수 있다.

5. ES6 문법

ES6는 새로운 언어 기능이 포함된 주요 업데이트이다. 다음과 같은 기능을 포함한다.

  • const: const는 var보다 강력하고 일단 사용되면 변수를 다시 할당할 수 없다.
  • let: let은 const와 비슷하고 변수는 범위 내에서만 사용이 가능하다.
  • Arrow function (화살표 함수): 코드가 깔끔해 보인다는 장점이 있다.
  • Template Literals (템플릿 리터럴): 억음부호 백틱(‘)과 표현식($)을 이용해 문자열 내에서 변수를 사용한다.
  • Promises (프로미스): 비동기 코드 방식이다.

동기(Synchronous)

  • 순차적/직렬적으로 태스크를 수행
  • 요청에 따른 응답이 이루어져야 다음 동작이 실행됨
  • 어떤 작업이 수행중이라면 뒤의 작업은 대기함. 블로킹(작업 중단)이 발생

비동기(Asynchronous)

  • 병렬적으로 태스크를 수행
  • 현재 작업의 종료 여부와 관계없이 다음 작업을 실행함
  • 완료 순서가 보장되지 않음. 블로킹이 발생하지 않음

자바스크립트는 싱글 스레드 기반으로 프로세스를 처리하고 동기 방식으로 코드를 이해한다. 하지만 무거운 작업은 비동기적으로 요청할 수 있다. 이벤트 루프를 이용해 비동기 작업을 수행할 수 있다. 비동기 작업을 만들 때 callback 함수를 함께 지정하는데 이를 가지고 후속 작업을 진행할 수 있다. 여기서 promise 객체와 callback이 하는 일은 동일하다.

 

6. Virtual DOM

Virtual DOM이란 DOM을 추상화한 가상의 객체이다.

Virtual DOM은 수정 사항이 여러 가지 있더라도, 렌더링을 한 번만 실행한다.

DOM에 직접 접근하게 되면 사소한 변경 사항에도 전체가 재렌더링 되기 때문에 브라우저에 과부하가 온다. 성능이 느려지게 되는 문제점이 발생한다. 따라서 DOM에 직접 접근하는 방식은 피해야 한다.

실제 DOM에는 브라우저가 화면을 그리는데 필요한 모든 정보가 들어있어 실제 **DOM을 조작하는 작업은 무겁다. Virtual DOM을 만들어서 사용하면 변경 사항을 빠르게 파악, 반영할 수 있다.

Virtual DOM은 DOM이 생성되기 전과 수정 사항을 비교하여 달라진 부분만 DOM에게 전달하며 딱 한 번만 렌더링한다.

React는 STATE가 변경될 때마다 재렌더링이 발생하는데 그럴 때마다 Virtual DOM을 생성한다.

React는 항상 두 개의 Virtual DOM을 가진다.

  1. 렌더링 이전 화면 구조를 나타내는 Virtual DOM
  2. 렌더링 이후에 보이게 될 화면 구조를 나타내는 Virtual DOM

두 개의 Virtual DOM을 비교하는 것을 Diffing이라고 표현한다. Diffing을 이용하면 어떤 Element에 차이가 있는지 파악하기 쉽다.

따라서 React는 차이가 발생한 부분만 실제 DOM에 적용한다. 이 과정을 Reconciliation(재조정)이라고 한다.

그러나 Virtual DOM을 사용한다고 해서 사용하지 않을 때보다 무조건 빠른 것은 아니다. React에서는 지속적으로 데이터가 변화하는 대규모 애플리케이션 구축을 할 때 사용을 권장한다.

 

7. React

React 탄생 이유는 다음과 같다.

  1. HTML, CSS, JS 불편한 점 보완
  2. input focus
  3. 반복적인 코드 사용
  4. 컴포넌트에 지정하고 재사용 ⇒ 유지 보수 문제 해결
  5. 페이지 이동 시 데이터를 매번 불러오는 것 방지화면 깜빡임 ⬆ UX⬇
  6. → 서버가 할 일이 많아진다.
  7. HTML 파일을 불러온다는 것 = 새로고침이 필요하다는 것

8. 클래스형 컴포넌트 vs 함수형 컴포넌트

선언 방식, state와 props 사용 차이, LifeCycle 사용 유무, 이벤트 핸들링에 대한 부분에서 차이점이 존재한다.

컴포넌트란 리액트의 기본 단위로 틀과 같은 개념이다.

틀(컴포넌트)은 같지만 데이터가 다른 경우 사용한다. (재사용)

대문자로 이름이 시작된다.

클래스형 컴포넌트

  • class 키워드가 필요하다.
  • Component로 상속을 받아야 한다.
  • render() 메서드가 필요하다.
  • state, lifeCycle 관련 기능 사용이 가능하다.
    • this.state 초기 값 설정이 가능하다.
    • constructor 없이 바로 state 초기 값 설정이 가능하다.
    • state는 객체 형식으로 존재한다.
    • this.setState 함수로 state 값 변경이 가능하다.
  • 메모리 자원을 함수형 컴포넌트보다 더 사용한다.
  • 임의 메서드를 정의할 수 있다.
  • 이벤트 핸들링
    • 화살표 함수 선언이 가능하며 요소에 적용하려면 this를 붙여야 한다.
  • Props
    • this.props를 통해 값을 불러온다.
    • 부모 객체의 키 값, 자식 props를 활용한다.

함수형 컴포넌트

  • state, lifeCycle 관련 기능 사용이 불가하다. (Hook을 통해 해결)
    • useState 함수로 state를 사용한다.
    • useState 함수를 호출하면 배열이 반환되는데 첫 번째 원소는 현재 상태, 두 번째 원소는 상태를 바꾸어 주는 함수를 작성한다.
  • 메모리 자원을 클래스형 컴포넌트보다 덜 사용한다.
  • 컴포넌트 선언이 편하다.
  • 이벤트 핸들링
    • const 키워드 + 함수 형태로 선언해야 한다.
    • 요소에 적용하더라도 this가 필요없다.
  • Props
    • props를 불러올 필요 없이 바로 호출할 수 있다.

 

[함수형 컴포넌트를 선호하는 이유]

  • state를 사용하지 않고 단순하게 데이터를 받아(props) Hook들을 필요한 곳에 사용하며 Logic의 재사용이 가능하다는 장점이 있다.
  • 코드가 간결하고 가독성이 좋다.
  • render() 함수가 필요없다.

 

create-react-app

  • npx create-react-app 이름
  • cd 이름
  • npm start

 

9. Props

Props는 component의 생명주기 내에서는 불변이다. component 내부에서 변경 값이 있으면 안 되고 Read-Only(읽기전용)으로 봐야 한다.

Props는 별도의 코드를 작성하지 않아도 React가 component 객체에 자동으로 생성해준다.

Props는 두 가지 방법으로 사용이 가능하다.

  1. 부모로부터 설정: 부모가 해당 component를 생성할 때 값을 설정
  2. 기본 값을 설정하여 기본 값으로 동작

Props 예시

  1. 부모 컴포넌트에서 Props 값 사용

10. State

State는 component 내부에서 변화할 수 있는 값이다.

Props는 부모 component에서 값을 설정하여 자식 component로 전달하거나 기본 값을 지정하여 읽기 전용으로 사용되었다면 State는 쓰기 전용이다.

Props의 경우, App.js에서 name을 설정해 주었을 때 name이 쓰이는 곳은 부모 component가 아닌 자식 componenet인 Second.js이다. 하지만 Second.js에서는 name을 수정할 수 없다. name을 수정할 수 있는 component는 App.js이다.

State는 useState를 이용해서 구현한다.

state가 변경되면 component가 re-rendering된다.

 

11. 라우팅 및 페이지 이동

link

useNavigate

useEffect

 

12. Redux

Redux란 JavaScript 상태 관리 라이브러리이다.

데이터가 집중화 되어 있어서 예측이 가능하고 데이터의 흐름이 단방향적이라 디버깅이 쉽다. (Store안에 저장된 상태는 오직 read-only이고, 무슨 일이 일어나는지를 정의하는 객체는 action이다.

 

Store

Store란 상태가 관리되는 공간이다.

컴포넌트에서 상태 정보가 필요할 때 이용한다.

데이터의 원천은 항상 Store이며 모든 변경 사항이 기록된다.

상황과 필요에 따라 Store은 여러 개 만들 수 있다.

Action

 

Action이란 App에서 Store에 전달할 데이터를 말한다.

JavaScript 객체 형식으로 되어있다.

Action은 Reducer가 구분할 수 있도록 액션 타입과 데이터를 가진 객체 형식이다. Reducer에 있는 Action 타입들을 받아와 외부에서도 Action을 일으킬 수 있도록 type과 Data를 받아 새로운 State로 설정할 수 있도록 Action들을 선언한다. State는 Action을 통해서만 바꿀 수 있으며 그 외의 상황에서는 State를 읽는 것만 가능하다.

Reducer

 

Action에서 받은 내용을 Store에 전달한다.

Action → Reducer → Store

Action을 Reducer에 전달하기 위해서는 dispatch() 메소드를 사용해야 한다.

  1. Action 객체 → dispatch() 메소드
  2. dispatch(액션) → Reducer 호출
  3. Reducer → 새로운 Store 생성

데이터의 변경은 Reducer를 통해서 일어나며 데이터는 Store에 저장된다.

 

useDispatch

useDispatch()는 Store에서 제공하는 함수 중 하나로 Action을 발생시켜준다.

useState

Hook 기능 중 하나이다.

useState를 사용할 때 배열 비구조화 할당을 사용한다.

비구조화 할당이란 [state, setState] 구조로 state는 현재 상태를 저장한 값, setState는 state 상태를 변경하는 함수이다. setState는 setter 함수라고 부르며 값을 변경할 때는 state에 직접 접근해서 변경하는 것이 아닌 반드시 setter을 이용해서 바꾸어야 한다.

useState를 이용해서 state 변수 생성하는 방법

  • useState import하기
  • state 변수의 초기 값 받기
  • state 변수와 해당 변수의 값을 바꿀 때 사용하는 setter 함수를 return. 배열 비구조화 할당을 사용해서 state 변수와 setter 함수를 받아온다.

 

13. OPEN API 활용하여 자신만의 웹서비스 제작하기

날씨 api (OpenWeatherMap)

 

14. 소셜 로그인(카카오톡 아이디로 로그인 같은) 한가지 이상 구현해오기(이름, 이메일 값 가져오기)