[ 인프런 워밍업 클럽 Study FE 0기 ] Week 3 발자국

[ 인프런 워밍업 클럽 Study FE 0기 ] Week 3 발자국

발자국

3주 동안 진행된 스터디 클럽이 마무리되었습니다. 이번 스터디에서는 Next와 타입스크립트에 대해서 기초를 다지는 한 주를 보냈습니다. 이제 인프런 워밍업 클럽 스터디의 마지막 발자국을 남깁니다!


요약

Section 06-07. TDD 기본 및 간단한 앱 생성 및 배포

대부분이 실습 위주였기에 코드가 궁금하다면 강의를 보자. 필요한 이론 개념만 요약하겠다.

[ TDD(Test Driven Development) 란? ]

TDD는 Test Driven Development의 약자로 테스트 주도 개발이라는 의미를 가지고 있다. 강의에서는 다음과 같이 설명한다.

  • “실제 코드를 작성하기 전에 테스트 코드를 먼저 작성하는 것”

    • 테스트 코드를 작성한 후 그 테스트 코드를 Pass 할 수 있는 실제 코드를 작성한다.

    • 원하고자 하는 기능의 테스트 코드 작성 ⇒ 테스트 실행 FAIL ⇒ 테스트 코드에 맞는 실제 코드 작성 ⇒ 테스트 실행 PASS

TDD는 테스트 코드를 작성한 뒤에 실제 코드를 작성한다. 단, 설계 단계에서 프로그래밍의 목적, 테스트 케이스를 작성해야 한다.

  1. 요구 사항 접수

  2. 요구 사항 분석 및 설계 ⇒ 목적 및 테스트 케이스 결정

  3. 테스트 코드 작성

  4. FAIL (오류, 수정)이 난 코드를 테스트 케이스에 추가 후 이를 바탕으로 재 설계

  5. 테스트가 통과 (PASS)된 코드만 개발 단계에서 실제 코드로 작성

⇒ 반복적으로 코드의 테스트를 진행함으로서 오류 개발을 낮추고 소스 코드를 깔끔히 관리하는 것. 따라서 다음과 같은 장점이 있다.

  • 디버깅 시간 단축

  • 재 설계 시간 단축

  • 오류 발생 확률 저하

  • 추가 구현 용이

  • 테스트 기간 단축

이렇게 보면 엄청나게 좋아 보이지만 모든 개발자들이 TDD 방식을 사용하지는 않는다. 아래 예시에서 첫 번째가 큰 듯 하다.

  • 익숙한 기존 방식을 버리지 못함

  • 생산성 저하

 

[ React Testing Library ]

 React Testing Library는 사용자가 컴포넌트를 사용하는 것처럼 테스팅하는 React의 테스트 라이브러리이다.

  • React Testing Library는 React 구성 요소 작업을 위한 API를 추가하여 DOM Testing Library 위에 구축된다.

  • DOM Testing Library란 DOM 노드를 테스트하기 위한 매우 가벼운 솔루션이다.

  • Create React App으로 생성된 프로젝트는 React Testing Library를 지원하기 때문에 따로 설치할 필요가 없다.

  • 행위 주도 테스트(Behavior Driven Test)이다.

    • EX) 사용자가 어떠한 행위로 이벤트가 발생되었을 때 프로그램이 어떻게 반응하는지~

     

 [ Jest ]

Jest는 현: Meta / 전: Facebook에서 만든 테스팅 프레임워크이다. 최소한의 설정으로 동작하며 Test case를 만들어서 어플리케이션 코드가 잘 돌아가는지 확인해준다

  • Jest는 테스트 실행 환경을 제공한다.

  • DOM이 없다(참고로 DOM 없이 React 테스트 X) ⇒ 따라서 React Testing Library와 함께 사

Jest를 사용하려면 설치를 해야한다.

  1. 라이브러리 설치: npm install jest —save-dev

  2. Test 스크립트 변경: “test” : “jest” OR “jest —watch All”

  3. 테스트를 작성할 폴더 및 파일 기본 구조 생성

 

Section 08. Next.js와 TypeScript

[ NextJS ]

Next.js란 SSR(Server-Side-Rendering)을 쉽게 구현할 수 있게 도와 주는 React 프레임워크이다.

일반적으로 리액트는 SPA(Single-Page Application)를 이용해서 CSR(Client-Side-Rendering)을 하기 때문에 좋은 점도 많지만, 검색엔진 최적화(SEO)에 관한 단점이 있다.

 

[ CSR과 SSR ]

💡 사전 지식: 검색 엔진에 도움을 주는 것은 HTML의 시맨틱 태그들이다!

 1. CSR (Client-Side-Rendering)

  • React에서는 CSR 방식 기본적으로 사용

  • CSR 초기 접속 시 렌더링 동작 방식:

  1. 클라이언트가 서버에 페이지 내놔 요청

  2. 서버는 빈 페이지를 클라이언트에게 전달 ⇒ 실제로 개발자 모드로 가면 HTML에 뼈대만 있는 것을 볼 수 있다.

  3. 클라이언트는 JS 파일을 보고 렌더링 ⇒ 즉, 빈 페이지를 클라이언트에서 처리한다. ⇒ 서버에 대한 의존도가 별로 없다.

결론: 검색 엔진에 영향을 주는 HTML이 빈 페이지니까 검색 엔진에 노출될 일이 거의 없다.

 

[ SSR ]

  • Next.js에서 사용하는 방식

  • React에서도 이 방식을 사용할 수 있으나 구현이 어렵기 때문에 React로 굳이?라는 느낌.

  • SSR초기 접속 시 렌더링 동작 방식:

  1. 클라이언트가 서버에 페이지 내놔 요청

  2. 서버는 미리 구성된 정적 파일을 클라이언트에게 전달. (정적 파일: HTML, CSS …)

  3. 클라이언트는 전달 받은 스크립트를 실행하여 화면을 브라우저에 그림

결론: 빈 페이지가 아닌 화면을 보여주기 때문에 SEO에 장점이 있다.

Next.js 설치 방법 (필자가 npx만 사용해서 npx만 기록)

  • npx create-next-app@latest

  • npx create-next-app@latest —typescript

 

 [ create-next-app 기본 구조 ]

image

Pages

  • 이 폴더 안에 페이지들을 생성

    • 만약 about이라는 페이지를 만드려면 pages폴더 안에 about.tsx를 생성해주면 된다.

  • index.tsx가 처음 “/” 페이지로 지정된다.

  • _app.tsx는 공통되는 레이아웃을 작성한다.

    • 모든 페이지에 공통으로 들어가는 걸 넣어주려면 여기에 넣어주면 된다.

    • url을 통해 특정 페이지에 진입하기 전 통과하는 인터셉터 페이지다.

  •  public

    • 이미지 같은 정적(static) 에셋들을 보관

       

       

       

       

       

       

       

     

  •  

    styles(강의에서는 있는데 내 폴더에는 없다..)

     

    • 스타일링을 처리해주는 폴더

       

    • 모듈(module) css는 컴포넌트 종속적으로 스타일링하기 위한 것이며, 확장자 앞에 module을 붙여줘야한다.

     

  • next.config.js

     

    • Next.js는 웹 팩을 기본 번들러로 사용한다.

       

    • 그래서 웹 팩에 관한 설정들을 이 파일에서 해줄 수 있다.

       

       


    [ Pre-rendering ]

    서버에서 각 페이지의 HTML 파일을 미리 생성하는 것으로, 모든 페이지가 pre-render된다. 이렇게 하기 때문에 SEO 검색 엔진 최적화가 좋아진다.

     

     

     

     

     

     

     

     

     

     

     

 

[ Data Fetching ]

Next.js에서는 데이터를 여러 방법으로 가져온다. 상황에 맞는 것을 알아서 잘 사용하자.

보통 React에서는 데이터를 가져올 때 useEffect 안에서 처리한다. 하지만 Next.js에서는 다른 방법을 사용해서 가져온다. (물론 Next에서도 useEffect를 이용해 가져올 수도 있다.)

  • getStaticProps: Static Generation으로 빌드할 때 데이터를 불러온다. (미리 한 번에 만들어 줌)

  • getStaticPaths: Static Generation으로 데이터에 기반하여 pre-render시 특정한 동적 라우팅 구현

  • getServerSideProps: Server Side Renderin으로 요청이 있을 때 데이터를 불러온다.

 

[ TypeScript ]

타입스크립트는 자바스크립트에 타입을 부여한 언어이다. 즉, 자바스크립트의 확장된 언어이다. 타입 스크립트는 자바스크립트와 달리 브라우저에서 실행하려면 파일을 한 번 변환해주어야 한다. 이 변환 과정을 컴파일(compile)이라고 한다.

타입스크립트의 특징을 정리해보자.

  • 자바스크립트의 타입 확장 버전

    • 즉, 동적 언어: 자바스크립트 / 정적 언어: 타입스크립트이다.

  • 개발 환경에서 에러를 잡는 걸 도와준다.

  • type annotations을 사용해서 코드를 분석할 수 있다.

  • 오직 개발 환경에서만 활성화 된다.

  • 타입 스크립트와 성능 향상은 관계없다.

    • 즉, 타입스크립트가 막 자바스크립트보다 성능이 뛰어나다!!!! 가 아니다.

       

자바스크립트는 굉장히 자유도가 높다. 하지만 이는 규모 큰 프로젝트를 진행한다면 오히려 독이 될 수 있다. (지옥의 타입 에러가 시작된다고 한다.) 뭐 이와 같은 이유로 타입스크립트 사용을 권장을 한다. 물론 필수 X

  • 타입스크립트는 자바스크립트를 단순화하여 더 쉽게 읽고 디버그할 수 있도록 한다.

  • 코드를 더 쉽게 읽고 이해할 수 있다.

  • 오픈 소스이다.

  • 정적 검사와 같은 자바스크립트 IDE 및 사례를 위한 매우 생산적이 개발 도구를 제공한다.

  • 자바스크립트보다 더 개선된 코드를 작성할 수 있다.

  • ES6의 모든 이점과 더 많은 생산성을 제공한다.

  • 고통스러운 버그에서 구출해준다.

 

[ TypeScript Type ]

타입이란 컴파일러에게 "야! 나 이 타입 쓸거다?"라고 선전포고하는 것이다. 즉, 내가 어떠한 value를 사용할 것인지 추론이 가능하도록 표기하는 것. 이는 컴파일러에게도 좋겠지만 코드를 읽는 개발자도 편하다.

Primitive/Object types의 경우 다음과 같다. (이건 너무 기초에 기초니까 정리 PASS)

  • Primitive: string, number, boolean, null, undefined, symbol

     

  • Object : function, array, classes, object

     

타입 스크립트에서는 기본적인 타입 및 특별한 타입을 제공한다.

  • Any

    • 잘 알지 못하는 타입의 경우 사용

    • 서드 파티 데이터 로딩 시.. 도대체 뭔 데이터가 올지 모를 때 사용하면 된다.\

    • 물론 이런 "뭔 타입 올지 머르는데...?"와 같은 확실치 않은 것은 최대한 안 쓰는 게 좋다.

  • Union

    • 또는 이다. OR이니까 | 사용한다.

    • let code: string | number; 이렇게 하면 code의 값은 string 또는 number라는 뜻.

  • Tuple

    • 배열에 타입 지정하는 버전~

    • let ex: [number, string] = [1, "hello"];

  • Enum

    • enumerated type을 의미하며, 값들의 집합을 명시하고 이를 사용하도록 만든다.

    • 별도의 값을 설정하지 않으면 기본적으로 0 스타트이다.

  • Void

    • 반환될 때 반환되는 데이터가 없을 경우 쓴다.

    • 참고로 함수들에서 return에 반환할 데이터 명시 안 해도 기본적으로 undefined가 반환 된다.

    • 이렇게 반환되는 값이 없어서 undefined가 반환되는 경우 void 쓰면 된다.

  • Never

    • 아에 완전히 영원히 값이 반환할 일이 없는 경우.. 기본적으로 함수가 undefined를 반환하는데 그 조차도 하지 않는 경우에 쓴다.

    • 오류 리턴이나 영원히 끝나지 않을 무한 루프에서 쓴다.

       

     

[ annotation, type, interface ]

  • annotation: 개발자가 타입을 타입스크립트에게 말해주는법

const str: string = "Hello, World!";
const num: number = 1;
  • type: 이 키워드를 사용해서 내가 타입 정의가 가능하다.

type Person = {
  name: string,
  age: number
}
  • interface: type과 비슷하게 정의 가능~

interface Person = {
  name: string,
  age: number
}

다만 interface는 부가적인 기능이 많다고 한다. (나중에 찾아봐야겠다.)

 

[ Type assertion ]

타입스크립트에서는 시스템이 추론 및 분석한 타입 내용을 우리가 원하는 대로 얼마든지 바꿀 수 있다. 이때 "타입 표명(type assertion)"이라 불리는 메커니즘이 사용된다.

var foo = {};
foo.bar = 123; // 오류: 속성 bar가 존재하지 않음.
foo.bas = "hello"; // 오류: 속성 bas가 존재하지 않음.

컴파일러는 foo type이 빈 {}로 인식한다. 따라서 존재하지 않은 bar와 bas에 접근하려고 하는 것으로 보이기 때문에 당연히 오류를 낸다. 하지만 type assertion을 사용하면 이런 상황을 피할 수 있다.

interface Foo {
  bar: number;
  bas: string;
}

var foo = {} as Foo;
foo.bar = 123;
foo.bas = "hello";

저기 서 사용된 as가 type assertion이다.

완전 간단하게 "컴파일러야. { } (왼쪽에 명시된 얘)는 Foo(오른쪽)와 같으니까 의심하지 말고 Foo(오른) 처럼 사용해라"라는 뜻이다.

 

[ Next.js 13 ]

12에서 13으로 넘어가면서 Next.js가 많이 바뀌었다고 한다! 위에서 설명한 것은 12니까 이 강의가 굉장히 중요해 보였다. (현재 14.1까지 나와따)

다음 추가된 사항이고... 대부분 실습 위주 강의라서 간단하게 정리만 했다.

  • App Router

    • page 파일이 해당 경로의 페이지 컴포넌트 처리된다.

  • Layout

    • 기본 레이아웃 정의 가능.

    • 공통된 레이아웃을 적도 children을 감싸는 형식으로 하면 된다.

  • Server/Client Component

    • Next에서는 기본이 Server Component이다.

    • State, Hook, 이벤트 처리 및 브라우저 api 사용 => 이 경우 Client Component를 사용해야한다.

      • 코드 작성 전 맨 첫 줄에 "use client" 명시해주면 된다.

     

Section 09. 리액트 Version 18

새로 추가된 내용

  • Automatic batching

  • Suspense on the server

     

  • Transition

  • 등등...

     

     

[ Automatic batching ]

배칭은 업데이트 대상이 되는 상태 값들을 하나의 그룹으로 묶어서 한 번의 리렌더링에 업데이트가 모두 진행될 수 있게 해주는 것이다. 하나의 함수 내부에서 여러 개의 state를 조작했을 경우 리렌더링이 그 state의 수 만큼 실행되는 것이 아니라 딱 1번만 최종 실행된다는 것이다. 그리고 제목에서 보이듯이 자동처리다. 개발자가 딱히 배칭을 위해 설정할 것은 없다.

  • 더 나은 성능을 위한 더 적은 리렌더링 가능

  • 이벤트 핸들러 밖에서도 작동

  • 필요할 때 제외 가능

     

     

 

[ Suspense on the server ]

  • 서버 사이드 렌더링

  1. 서버에서 전체 앱에 대한 데이터 가져옴

  2. 서버에서 전체 앱을 HTML로 렌더링하고 응답으로 보냄

  3. 클라이언트에서 전체 앱에 대한 자바스크립트 코드 로드

  4. 클라이언트에서 자바스크립트 논리를 전체 앱에 대해 서버 생성 HTML에 연결(hydration)

 

[ Transition ]

  • 리액트에서 어떠한 업데이트가 Urgent하며 어떠한 것이 그러하지 않은지 알려준다.

 

Section 10. 리덕스

리덕스는 자바스크립트의 애플리케이션위한 상태 관리 라이브러리이다.

  • CreateStore()

    • 앱의 전체 상태 트리를 보유하는 Redux 저장소를 만든다.

    • 앱에는 하나의 스토어만 있어야 한다.

  • getState()

    • 애플리케이션의 현재 상태 트리를 반환한다.

  • subscribe(listener)

    • listener 함수 등록

    • Action이 dispatch될 때마다 리스너 함수가 호출된다.

    • 그런 다음 getState()를 호출하여 콜백 내부의 현재 상태 트리를 읽을 수 있다.

     

[ Provider ]

<Provider> 구성 요소는 Redux Stroe 저장도에 액세스해야 하는 모든 중첩 구성 요소에서 Redux Store 저장소를 사용할 수 있도록 한다.

React Redux 앱의 모든 Reqact 구성 요소는 저장소에 연결할 수 있으므로 대부분의 응용 프로그램은 전체 앱의 구성 요소 트리가 내부에 있는 최상위 수준에서 <Provider>를 렌더링한다.

그런 다음 Hooks 및 연결 API는 React의 컨텍스트 메커니즘을 통해 제공도니 저장소 인스턴스에 액세스할 수 있다.

 

[ useSelector, useDispatch ]

리덕스 HOOK

  • useSelector

    • 스토어의 값을 가져올 수 있다.

  • useDispatch

    • store에 있는 dispatch 함수에 접근.

 

[ 리덕스 미들웨어 ]

Redux 미들웨어는 액션을 전달하고(dispatch) 리듀서에 도달하는 순간 사이에 사전에 지정된 작업을 실행할 수 있게 해주는 중간자이다.

💡 로깅, 충돌 보고, 비동기 API 통신, 라우팅 등을 위해 미들웨어를 사용한다!

미들웨어 생성에 관한 것은 강의에서 실습으로 소개하니 궁금하면 강의를 보자.

 

[ 커링 ]

  • 자바스크립트 고급 기술이다. (다른 언어에도 존재.)

  • f(a, b, c)처럼 단일 호출로 처리하는 함수를 f(a)(b)(c)와 같이 각각의 인수가 호출 가능한 프로세스로 호출된 후 병합될 수 있게 변환하는 것이다.

 

[ Thunk ]

리덕스를 사용하는 앱에서 비동기 작업을 할 때 많이 사용하는 방법이다. "thunk"라는 단어는 "일부 지연된 작업을 수행하는 코드 조각"을 의미하는 프로그래밍 용어이다. Redux 스토어의 dispatch 및 getState 메서드와 상호 작용할 수 있는 내부 로직이 있는 함수를 작성할 수 있다.

 

[ Redux Toolkit ]

  • Redux 툴킷은 Redux 로직을 작성하기 위한 공식 권장 접근 방식이다.

  • Redux 코어를 둘러싸고 있으며 Redux 앱을 빌드하는 데 필수적이라고 생각하는 패키지와 기능이 포함되어 있다.

  • Redux 툴킷은 Redux 작업을 단순화하고 일반적인 실수를 방지하고 Redux 애플리케이션을 더 쉽게 작성할 수 있다.

  • Redux 툴킷에는 Redux Thunk가 기본으로 들어가있다.

     

사용 순서:

  1. configureStore을 사용하여 Redux Store 만들기

  2. React 컴포넌트에 Redux Stroe 제공 순서

    1. 주위에 React-Redux <Provider>로 컴포넌트를 감싸준다.

    2. Redux Stroe를 <Provider store={store}>로 전달한다.

  3. creatSlice로 Redux 슬라이스 리듀서 생성

  4. React 컴포넌트에서 React-Redux useSelector/useDispatch Hook 사용


미션

과제 총 합본 https://www.inflearn.com/blogs/7021

React 미션 02. 디즈니+ 클론

과제 중에 가장 어려웠던 부분은 구글 연동이었습니다. 처음으로 구글 연동을 시도하면서 계속해서 오류가 발생했고, 한 번은 무한 로그인에 걸려 프로그램이 멈춘 적도 있었습니다. 이때는 정말 심장이 철렁거렸습니다. 그러나 마음을 비우고 처음부터 차근차근 시도하니 로그인 연동에 성공했습니다.

또 다른 어려움은 마우스를 대면 비디오가 나오는 부분이었습니다. 이미지와 비디오를 겹쳐놓고 마우스가 hover될 때 비디오만 보여주는 부분인데, CSS의 position 이해가 부족한 것인지 배치가 제대로 되지 않아 계속 시도해야 했습니다. position에 대한 부분은 추가적인 학습이 필요하다고 느꼈습니다.


React 미션 03. 포켓몬 도감

포켓몬 과제는 난이도가 상이었고 디즈니와 다르게 참고할 코드조차 없는 어려운 과제였습니다. 이것은 정말 자기 스스로 머리를 쪼개가며 해결 해야하는 과제로 보였기에 가장 마지막에 해결을 하겠다 생각했습니다. 포켓몬 도감를 시작할 때, 이제야 웹을 공부를 하는 제가 이 과제를 과연 완성을 할 수 있을까? 했는데, 걱정과 다르게 디즈니보다 훨씬 쉬었습니다...! 코드를 작성하면서 렌더링이 안 일어나는 이상한 상황을 겪었지만(map key 값이 고유하지 못해서 발생한 문제) 금방 해결하고 완성을 했습니다!! 그 밖에는 문제된 일은 없습니다. 제가 스스로 작성한 코드가 작동하는 것을 보니 정말 뿌듯하네요. 그리고 예시와 다르게 UI를 상당히 많이 바꿨습니다...! 미션을 하면서 가장 즐거웠던 과제였습니다👍

 

React 미션 04. Next, TypeScript을 이용한 퀴즈 앱

이번 프로젝트에서는 라우팅을 처리하기 위해 사용한 useRouter에서 문제가 발생했습니다. 문제를 해결하려고 찾아보니, next/router 대신에 next/navigation을 사용해야 한다는 것을 알게 되었습니다. 그것을 마지막으로 문제 없이 잘 과제를 끝 맞추었습니다.


회고

워밍업 스터디를 처음 시작할 때에는 HTML/CSS, JS의 기초만 약간 알고 있었고, 부트캠프나 프로젝트 경험이 없었습니다. 또한, 외적인 사정과 긴 강의 시간, 다양한 미션으로 인해 시간적으로도 부족함을 느꼈습니다. 하지만 저 자신의 발전을 위해서 새벽 3~4시까지 시간을 투자해나가며 수업과 미션을 해결해나갔습니다.

또한, 저는 코틀린을 사용한 경험이 있는데, 타입 스크립트가 코틀린과 유사하다는 느낌을 받아서 타입 관련 공부가 수월했습니다. 하지만 타입스크립트의 심화 부분과 Next.js, 리덕스 등에 대해서는 추가적인 공부가 필요하다고 생각하고 있습니다.

3주간의 스터디는 성장감을 느끼게 해주었습니다. 그렇기에 이미 끝났다는 사실이 아쉽기도 합니다. 이 소중한 경험을 제공해 준 인프런과 스터디를 이끌어주신 강사님에게 깊은 감사의 인사를 전합니다.

앞으로도 계속해서 성장하고 발전하기 위해 노력할 것이며, 새로운 도전들을 마주하면서 더욱 성장해 나가고 싶습니다. 감사합니다! 🌱

댓글을 작성해보세요.