3 프론트엔드 개발

3.1 프론트엔드 개발환경 설정

3.1.1 Node.js 와 NPM 설치

  • 프론트엔드

    • 사용자 바로 앞에서 사용자와 상호작용

    • 애플리케이션 로직을 수행하고 백엔드 서버로 요청을 보냄

    • 웹 서비스에서 클라이언트 혹은 프론트엔드란 웹 브라우저를 뜻함

      • 사용자는 자신의 컴퓨터에서 브라우저 실행

      • 브라우저는 인터넷을 이용해 서버에 있는 자원(HTML, JavaScript, CSS)을 사용자의 컴퓨터로 다운로드 및 실행

  • Node.js

    • Node.js가 등장하기 전까지 자바스크립트는 브라우저 내에서만 실행 가능

      • 즉, JS는 브라우저상에서 HTML 렌더링의 일부로 실행하거나 개발자창의 자바스크립트 콘솔을 이용해 실행

    • Node.js는 자바스크립트를 컴퓨터에서 실행할 수 있게 해주는 JS 런타임 환경

      • 이는 곧 JS를 클라이언트 언어뿐 아니라 서버 언어로도 사용할 수 있다는 뜻

    • Node.js는 구글 크롬의 V8 자바스크립트 엔진을 실행

  • NPM (Node Package Manager)

    • Node.js의 패키지 관리 시스템

    • NPM을 이용해 npmjs에서 Node.js 라이브러리를 설치

    • Node.js를 설치하면 함께 설치

node 프로젝트를 초기화하려면, npm init을 사용 (여기서는 npx라는 툴로 리액트 애플리케이션을 초기화할 예정)

3.1.2 비주얼 스튜디오 코드 설치

3.1.3 프론트엔드 애플리케이션 생성

리액트 애플리케이션 생성

프로젝트 폴더로 이동 및 애플리케이션 실행

  • 비주얼 스튜디오 코드에서 개발 환경 설정

    • 비주얼 스튜디오 코드에 워크스페이스 생성

      • File → Add Foler to Workspace

  • create-react-app 기본 생성 파일

    • package.json

      • 프로젝트의 메타데이터로 사용할 node.js 패키지 목록 등을 포함

    • public 디렉터리 아래 파일

      • index.html

        • http://localhost:3000이 가장 처음으로 리턴하는 HTML 파일

        • 리액트에서 html 파일은 index.html 하나 밖에 없음

        • 다른 페이지들은 React.js를 통해 생성되고 index.html에 있는 root 엘리먼트 아래에 동적으로 랜더링

    • src 디렉터리 아래의 파일

      • index.js는 index.html과 함께 가장 처음으로 실행되는 JS 코드

      • 이 자바스크립트 코드가 리액트 컴포넌트를 root 아래에 추가

      • App.js는 기본으로 생성된 리액트 컴포넌트

3.1.4 material-ui 패키지 설치

material-ui/core 설치

material-ui/icons 설치

3.1.5 브라우저의 동작 원리

  • 브라우저 동작 원리

    • 브라우저 주소창에 https://google.com 같은 웹 주소를 입력하면

    • 브라우저는 HTTP GET 요청을https://google.com의 서버로 전송

    • 보통 프론트엔드가 있는 웹 서비스의 경우 HTML 파일을 결과로 반환

  • HTML을 받은 후 텍스트로된 HTML을 브라우저에 보여주기까지

    1. 파싱

      1. 브라우저는 HTML을 트리 자료 구조 형태인 DOM 트리로 변환

      2. IMAGE, CSS, SCRIPT 등 다운로드해야 하는 리소스를 다운로드 (CSS의 경우 다운로드 후 CSS를 CSSOM 트리로 변환)

      3. 다운받은 자바스크립트를 인터프리트, 컴파일, 파싱 및 실행

    2. 렌더링

      1. DOM 트리와 CSSOM 트리를 합쳐 렌더 트리를 만듬

        • 내용인 DOM과 디자인인 CSSOM을 합침

        • 트리의 각 노드가 브라우저의 어디에 배치될지, 어떤 크기로 배치될지를 정하는 것

      2. 브라우저 스크린에 렌더 트리의 각 노드를 그려줌

위와 같은 2 단계를 거치면 사용자는 브라우저상에서 시각화된 HTML 파일을 볼 수 있게 됨

개발자툴 → 디버깅창 : HTML Elements, CS, 자바스크립트 콘솔, 네트워크 탭, Application 탭

3.1.6 React.js

  • SPA (Single Page Application)

    • 웹 페이지를 로딩하면 사용자가 임의로 새로 고침하지 않는 이상 페이지를 새로 로딩하지 않는 애플리케이션

    • 서버에게 새 HTML 페이지를 요청하지 않고 자바스크립트가 동적으로 HTML을 재구성

    • 브라우저의 자바스크립트는 fetch, ajax 등의 함수로 서버에 데이터를 요청하고 받은 데이터를 이용해 자바스크립트 내에서 HTML 재구성

  • React.js 첫 화면

    • 하얀 화면 : index.html 로딩중

      • HTML이 <body></body>를 렌더링하다보면 마지막에 bundle.js라는 스크립트 로딩

      • bundle.js는 npm start를 실행했을 떄 만들어지는 스크립트인데, index.js를 포함

      • index.js의 일부로 ReactDom.render() 함수가 실행

      • render() 함수가 동적으로 HTML 엘리먼트를 리액트 첫 화면으로 바꿔줌

      • 이떄 렌더링된 하위 엘리먼트는 render() 함수의 매개변수로 들어가는 <App /> 부분

  • React 컴포넌트

    • 컴포넌트는 자바스크립트 함수 또는 자바스크립트 클래스 형태로 생성할 수 있음

  • JSX

    • React가 한 파일에서 HTML과 자바스크립트를 함께 사용하려고 확장한 자바스크립트 문법

    • JSX 문법은 Babel이라는 라이브러리가 빌드 시 자바스크립트로 번역해 줌

ReacrDOM은 매개변수로 받은 <App /> 컴포넌트를 이용해 DOM트리를 만들고, 이때 컴포넌트의 render() 함수가 반환한 JSX를 렌더링 함

  • import를 이용해 App 컴포넌트를 불러옴

  • <컴포넌트이름 />을 이용해 컴포넌트를 사용

  • ReactDOM.render

    • 첫 번째 매개변수로 리액트 컴포넌트를 받음

    • 두 번째 매개변수로는 root 엘리먼트를 받음

      • root 엘리먼트에 첫 번째 매개변수로 넘겨진 리액트 컴포넌트를 root 엘리먼트 아래에 추가하라는 뜻

      • root 엘리먼트는 index.html에 정의되어 있음

3.2 프론트엔드 서비스 개발

⚠️ HTML Mock을 우선적으로 작성하고 UI에 들어가게 될 가짜 데이터 작성

3.2.1 Todo List

  • Props와 State 적용, material-ui 적용

3.2.2 Todo 추가

  • Add 핸들러 추가

    • onInputChange : 사용자가 input 필드에 키를 하나 입력할 때마다 실행되며 input 필드에 담긴 문자열을 자바스크립트 오브젝트에 저장

    • onButtonClick : 사용자가 + 버튼을 클릭할 때 실행되며 onInputChange에서 저장하고 있던 문자열을 리스트에 추가

    • enterKeyEventHandler : 사용자가 input 필드상에서 엔터 또는 리턴키를 눌렀을 때 실행되며 기능은 onButtonClick과 같음

3.2.3. Todo 삭제

3.2.4 Todo 수정

  1. 체크박스에 체크하는 경우

  2. 타이틀을 변경하고 싶은 경우

3.3 서비스 통합

3.4.1 componentDidMount

  • 렌더링 과정

    • 리액트는 브라우저에 보이는 HTML DOM 트리의 다른 버전인 ReactDOM(Virtual DOM)을 갖고 있음

    • 어떤 이유에서든 컴포넌트의 상태(state)가 변하면 ReactDOM은 이를 감지하고 변경된 부분의 HTML을 바꿔줌

    • HTML이 업데이트되면 우리는 변경된 결과를 눈으로 확인

  • 마운팅 과정

    • 랜더링이 맨 처음 일어나는 순간,

    • 즉 ReactDOM 트리가 존재하지 않는 상태에서

    • 리액트가 처음으로 각 컴포넌트의 render() 함수를 콜해 자긴의 DOM 트리를 구성

CORS 에러 메세지 뜸

3.4.2 CORS

  • CORS (Cross-Origin Resource Sharing)

    • 처음 리소스를 제공한 도메인이 현재 요청하려는 도메인과 다르더라도 요청을 허락해 주는 웹 보안 방침

    • CORS가 가능하려면 백엔드에서 CORS 에서 방침 설정을 해줘야 함

3.4.3 fetch

  • 비동기 오퍼레이션

    • 만약 내가 HTTP 요청을 백엔드에 보냈는데 백엔드가 이를 처리하는 데 1분이 걸리면 내 브라우저는 1분간 아무것도 못하는 상태가 됨

  • 콜백 함수

    • 오퍼레이션이 현재 실행 중인 자바스크립트 스레드가 아니라 드른 곳에서 실행된다면, HTTP 응답을 받았다는 사실을 콜백 함수를 통해 알 수 있음

  • 콜백 지옥

    • XMLHttpRequest를 사용하는 경우 콜백 함수 내에서 또 다른 HTTP 요청을 하고 그 두 번째 요청을 위한 콜백을 또 정의하는 과정에서 코드가 굉장히 복잡해짐.

  • Promise

    • 콜백 지옥을 피할 수 있음

    • 비동기 오퍼레이션에서 사용

    • 이 함수를 실행한 후 Promise 오브젝트에 명시된 사항들을 실행시켜 주겠다는 약속

    • 세 가지 상태, Pending, Resolve, Reject가 있음

      • pending : 오퍼레이션이 끝나길 기다리는 상태

      • resolve : 오퍼레이션이 성공적으로 끝남. 이때 resolve는 then의 매개변수로 넘어오는 함수를 실행

      • reject : 오퍼레이션 중 에러가 나는 경우. 그 결과 catch 매개변수로 넘어오는 함수가 실행

    • them이나 catch로 넘기는 함수들은 지금 당장 실행되는 것은 아님

      • 실제 함수들이 실행되는 시점은 resolve와 reject가 실행되는 시점

  • Fetch API

    • API 서버로 http 요청을 송신 및 수신

    • 자바스크립트가 제공하는 메서드

    • url을 매개변수로 받거나 url과 options을 매개변수로 받음

    • fetch()함수는 Promise 오브젝트를 리턴

    • then과 catch에 콜백 함수를 전달해 응답을 처리

  • fetch는 첫번째 매개변수로 uri를 받음

  • 디폴트로 GET 메서드를 사용

  • then에는 응답을 받은 후 실행할 함수 response ⇒ {}를 매개변수로 넘김

  • catch에는 예외 발생 시 실행할 함수 e ⇒ {}를 넘김

  • 메서드를 명시하고 싶은 경우나 헤더와 바디를 함께 보내야 할 경우에는 아래와 같이 주 번째 매개변수에 요청에 대한 정보가 담긴 오브젝트를 넘겨줌

  • 하드코딩된 “localhost:8080/todo” 리팩터링

src/api-config.js

  • 백엔드로 요청을 보낼 때 사용할 유틸리티 함수를 작성

Todo Update 수정

  • 프론트엔드 UI 부분을 위한 mock() 함수에서는 사용자가 키보드에서 입력하면 editEventHandler 함수가 title을 수정해 줌

  • 따로 update() 함수를 App.js에 만들지 않아도 잘 동작

  • 하지만 API를 이용해 update하려면 Serve API를 이용해 서버 데이터를 업데이트한 후

  • 변경된 내용을 화면에 다시 출력하는 두 가지 작업이 필요

Last updated