Next.js에서는 fetch의 사용을 권장한다. 그 이유는 데이터 캐싱 기능을 자동으로 적용시켜주시 때문에 다른 데이터를 호출하는 것에 비해 성능면에서 뛰어나기 때문이다.

 

먼저 함수에 async를 걸어주고 fetch를 불러오면된다.

export default async fntion MyComponent(){
	const MyDat = await fetch("url", {option});
}

해당 방식으로 호출해주면 된다.

근데 여기서 중요한 점은 axios의 경우 JSON 처리를 해주지 않아도 되지만 fetch로 불러오는 데이터는 JSON 변환을 해주어야한다. 이는 데이터를 불러오는 과정에서 보여주는 걸로 하고 Next에서 지원하는 기능에 대한 알아보자

 

- cache 옵션 설정

1.

fetch("url", {cache: 'force-cache' | 'no-store'});

데이터 캐시에서 일치하는 요청을 찾는다

  • 일치하고 최신일 경우 > 캐시에서 반환해준다.
  • 일치 x, 오래된 경울 > 원격 서버에서 리소스를 가져오고 캐시에 저장하지 않는다

2.

fetch("url",  {next:{revalidate: false | 0 | number}});

리소스의 캐시 수명을 설정한다.

  • false : 리소를 무기한 캐시한다. HTTP 캐시는 시간이 지남에 따라 오래된 리소스를 제거할 수 있다.
  • 0 : 리소스가 캐시되는 것을 방지한다.
  • number : 리소스 캐시 수명이 최대 n초임을 지정한다.
더보기

알아둘만한 것

- 개별 fetch 요청이 경로의 기본값보다 낮은 숫자로 수명을 설정하며 전체 경로의 재검증 시간으 줄어든다.

- 동일한 경로, 동일한 url을 사용할때 revaildate 값이 더 낮은 값을 사용한다.

- 옵션이 충돌하면 에러가 발생한다. 

ex) {revaildate : 0, cache: force-cache}, {revaildate: 10, cache: no-store}

 

위의 내용에서 '리소스를 캐시한다'라는 문장에서 캐시란 무엇일까?

 

먼저 리소스에 대해 알아야한다.

리소스 : HTTP에서 리소스란 웹 브라우저가 HTTP 요청으로 가져올 수 있는 모든 종류의 파일을 말한다.

 

위와 같은 리소스를 미리 복사해 저장해 놓는 임시 저장소가 바로 cache이다. 

이러한 캐시를 통해 이전에 불러온 리소스를 다시 불러오기 전에 캐시에서 탐색하여 해당 리소스가 존재한다면 다시 불러오지 않고 캐시에서 꺼내 사용한다. 이 방식을 통해 데이터 페칭 과정을 줄여 성능 및 효율성을 높일 수 있는 것이다.

 

개발을 하기 전 왜 이 기술들을 사용하는지 먼저 알아보는 것이 중요하다고 생각한다. 각 기술들에 대해 정리를 한 후 틱택토 만들기를 시작할 것이다.

 

React

1. Virtual DOM 사용

 기존의 웹사이트 구현 방식은 웹 브라우저가 웹사이트의 텍스트 문서를 읽어서 DOM이라는 트리 구조로 바꾸어 사용자에게 보여주고, 웹 개발자는 사용자들에 반응에 따라 웹사이트를 갱신하는 방식이다. 하지만 작은 변화들을 매번 갱신하는 것은 효율적이지 못하고 성능에 좋지 않다. 이러한 문제를 해결하기 위해 React는 Virtual DOM을 사용하여 개발자들이 변화를 주고 싶은 부분만 Virtual DOM에서 수정하고 원래  DOM과의 차이점을 비교해 그 차이점만 반영하며 성능을 향상 시킨다.

2. 기존 DOM의 문제를 해결하기 위해 나온 기술들 중 유일하게 라이브러리임
 사실 기존의 DOM의 방식에 한계를 느껴 Vitual DOM을 적용한 것은 React만이 아니다. React를 제외하고 대표적으로 Angular.js와 Vue.js가 있다. 근데 이들보다 React를 많이 사용하는 이유는 무엇일까? Vue와 Angular는 프레임워크인 반면 React는 라이브러리이기 때문이다. 전체적인 구조와 규칙이 강하게 정해져 있어 그들의 규칙을 따라야하는 프레임워크에 비해 기존 자바스크립트 기반의 문법을 사용할 수 있는 React를 더 선호하는 것이다.

 

 대표적인 부분만 설명하고 넘어가겠지만 이것 이외에도 컴포넌트 기반 아키텍처를 채택하여 컴포넌트를 쉽게 재사용하여 코드를 짜는 과정에서의 효율을 높여주는 것이나 리액트 네이티브의 강점 등 개발자들이 React를 채택한 이유는 정말 많고 다양하다.

 

TypeScript

 타입스크립트란 자바스크립트 기반의 정적 타입 문법을 추가한 프로그래밍 언어이다. 더 자세히 말하자면 자바스크립트의 상위 확장자로 자바스크립트의 엔진을 사용하며 자신이 원하는 변수의 타입을 정의하고 프로그래밍 할 시 자바스크립트로 컴파일하여 실행할 수 있도록 만들어진 언어이다.

 동적으로 타입을 지정하는 자바스크립트의 문제를 해결하고자 나온 언어이며 타입스크립트를 사용하며 컴파일 에러를 예방하고 손쉽게 디버깅을 할 수 있다. 그리고 자바스크립트의 슈퍼셋 즉 상위 확장자 이기 때문에 모든 자바스크립트 프로젝트를 커버할 수 있기 때문에 타입스크립트를 사용하는 것이다.

 

이러한 타입스크립트가 장점만 있는 것은 아니다. 매번 타입 지정을 해야하기에 이 과정에서 발생하는 에러를 해결하며 시간을 뺏기는 등의 생산성 저하가 발생할 수 있다. 근데 이를 해결하기 위한 방법 중 하나가 컴포넌트 기반 개발을 지원하는 라이브러리나 프레임워크를 사용하는 것인데, React가 바로 컴포넌트 기반 개발을 지원하는 라이브러이이다.

 

이 부분에서 React와 타입스크립트를 왜 같이 사용하는 알 수 있다.

- 타입의 종류

number

string

boolean

null

undefined

any(사용하지 않는 것이 좋다.)

...

 

- 간단한 타입 지정 방식 정리

 

▷ 기본 방식

  let 변수:타입지정 = 값

  ex) let b: string = "my Type";

여러 타입 지정

  let 변수: 타입 | 타입 = ~;

배열 지정

  let 변수 : 타입[] = [값, 값, ...]

 

▷ type

 export type 이름 = {

  변수 : 타입 ;

  변수 : 타입 ;

  ...

}

 

▷ generic 방식

  데이터를 부르는 순간에 타입을 정하고 싶을 때 사용

  ex) const [myValue, setMyValue] = useState<타입지정>()

 

▷ interface

보통 Props에 대한 타입을 지정할 때 사용

  inteface 이름 {

  변수 : 타입;

  변수 : 타입;

   ...

 }

 

▷ 함수 타입 지정

  함수를 작성해주고 함수의 리턴타입을 지정해준다. 리턴이 없다면 void로 지정해준다.

 

▷ extends (type에서도 비슷한 기능 존재 >> type 이름 = 기존에 있던 타입 $ {})

interface 이름 extends 기존에 만든 타입 {} 

위와 같이 적어서 기존에 있던 타입을 불러올 수 있다. 이 경우엔 중괄호 안에 아무것도 적지 않아도 된다. 추가된 변수가 있다면 적어준다.

 

▷ Omit

기존에 지정한 타입에서 어떤 것을 뺴고 싶을 때 사용한다.

export type 이름 = Omit<기존 타입, 빼고 싶은 변수 이름>

interface 이름 extends Omit<기존타입, 빼고 싶은 변수이름> {}

 

▷ Pick 

원하는 것만 선택하여 가져오고 싶을 경울 사용 

export type 이름 = Pick<타입 이름, 가져오고싶은 변수이름>

 

▷ API로 호출한 데이터에 타입 지정 (제네릭 문법 활용)

export type 이름<T>{

  data: T[ ],

  같이오는 값 변수 : 타입,

  ...

}

위처럼 지정한 후 API로 데이터를 호출할때 T부분에 불러오는 데이터 타입을 적어주면 된다.


emotion

왜 이모션을 사용하는지에 대해 몇가지를 알아봤다.

  • className이 자동으로 부여되기 때문에 스타일이 겹칠 염려가 없다.
  • 재사용이 가능하다.
  • styled component 사용방식과 css prop 기능을 지원하여 확장에 용이하다.
    • React 사용하기 위해 @emotion/react를 설치하고 styled component를 사용하기 위해 @emotion/styled를 설치한다. 
  • styled component보다 파일 사이즈가 작고, SSR시 서버 작업이 필요없다.

보통 styled component랑 비교를 많이 하는데 styled component보다 크기가 작고 SSR 서버 작업 없이 할 수 있다는 것에서 styled component에 비해 메리트가 있다고 생각했다. 그리고 className이 자동 부여되어 겹치는 것을 방지할 수 있는 것도 유용하기에 emotion을 사용하는 것 같다.

 

- emotion 사용 방법

설치

 

 

 

 

  • CSS Props
yarn add @emotion/react

 

(사용 예시 1)

 /** @jsxImportSource @emotion/react */
 //React의 jsx() 함수를 사용하지 말고 Emotion의 jsx() 함수를 사용한다.
 
import { css } from "@emotion/react";

css style = css`
	color: hotpink;
`

const SomeComponent = ({ children }) => (
	<div css={style}>
    	Some hotpink text.
        {children}
	</div>
);

const anotherStyle = css({
	textDecoration: 'underline'
});

const AnotherComponent = () => (
	<div css={anotherStyle}> Some text with an underline. </div>
)

render(
	<SomeComponent>
    	<AnotherComponent/>
    </SomeComponent>
)

 

(사용 에시 2 : 문자형)

import { css } from "@emotion/react";

export default function MyComponent(){
	return(
    <div
    	css={css`
        	color: blue;
        `}
    >
    문자형
    </div>
    );
}

 

(사용 예시 3 : 객체형)

import { css } from "@emotion/react";

function MyComponent() {
  return (
    <div
      css={css({
        color: "green",
      })}
    >
      객체형
    </div>
  );
}

 

 

  • styled-components
# assuming you already have @emotion/react installed
yarn add @emotion/styled

 

 

개발 환경 셋팅

1. yarn으로 Ts가 적용된 React 설치하기

yarn을 먼저 설치해준다

npm install --global yarn

 

Ts가 적용된 React 설치하기

yarn create react-app tic-tac-to --template typescript

 

 

2. @emotion/react와 @emotion/styled 설치하기

이렇게 React를 설치한 후 폴더로 들어가서 

yarn add @emotion/react @emotion/styled

를 해주면된다.

 

근데 여기서 에러를 만났다

사용할 권한이 없기 때문에 발생하는 에러라고 한다. 권한을 요청하기 위해서 Windows Powershell을 관리자 권한으로 실행해주고 

get-help Set-ExecutionPolicy

를 입력한 후에 Y를 입력하고,

Set-ExecutionPolicy RemoteSigned

를 입력한 후에 Y를 입력하면 권한 설정을 할 수 있다.

 

이렇게 한 후에 다시 입력해보니 별문제 없이 설치되었다.

이제 셋팅을 마무리했으니 개발을 해보자

클린코드 >> 명확한 이름, 중복 줄이기

 

1. 실무에서 클린 코드의 의의

안좋은 코드 : 흐름 파악이 어렵고, 도메인 맥락 표현이 안 되어, 동료에게 물어봐야 알 수 있는 코드 

 

실무에서의 클린 코드의 의의 == 유지 보수 시간의 단축

 

2. 안일한 코드 추가의 함정

타당하고 자연스러운 코드 추가도 나쁜 코드일 수 있다 

>> 하나의 목적인 코드가 흩뿌려져 있기 때문이다.

>> 하나의 함수가 여러가지의 일을 하고 있다.

>> 함수의 세부 구현 단계가 제각각이다.

 

리팩토링 

>> 함수의 세부 구현 단계를 통일한다. 

>> 하나의 목적인 코드는 뭉쳐두자.

>> 함수가 하나의 일만 하도록 쪼개자

 

클린코드 != 짧은 코드

== 원하는 로직을 빠르게 찾을 수 있는 코드

 

- 원하는 로직을 빠르게 찾는 방법은? 

1. 응집도 : 하나의 목적을 가진 코드가 흩뿌려져 있으면 안된다.

2. 단일 책임 : 함수가 여러가지 일을 하면 안되고 하나의 일만 해야한다.

3. 추상화 : 함수의 세부 구현 단계가 통일되어야 한다.

 

 - 응집도

무조건 한 군데로 뭉치는 것이 좋은 것은 아니다 >> 예를 들어 커스텀 훅으로 목적이 같은 코드를 묶어 그 커스텀 훅만 부른다면, 어떤 팝업을 띄우는지 바로 파악하기 힘들기에 오히려 코드 파악이 어려워진다.

 

--> 그렇다면 뭉쳐야 하는 것은 무엇일까 >> 당장 몰라도 되는 디테일이다. 

즉 코드 파악에 필수적인 핵심 정보는 뭉치면 안된다.

 

읽기 좋게 응집하는 법

- 남겨야할 핵심 데이터와 숨겨도 될 세부구현 기분을 잘하기

- 핵심 데이터는 밖에서 전달 나머지는 뭉치자

>>> 이렇게 핵심 데이터만 전달받고 세부 구현은 뭉쳐 숨겨 두는 개발 스타일이 "선언적 프로그래밍"이다

선언적 프로그래밍을 사용한다면, 재사용에 용이하고 무엇을 하는 함수인지 빠르게 이해할 수 있다

 

뭉치지 않은 것은 "명령형 프로그래밍"이라고 한다. 세부 구현이 모두 노출되어 있어 커스텀이 쉽지만 바로 어떤 함수인지 파악하기 힘들고 재사용이 어렵다.

 

- 단일 책임

하나의 일을 하는 뚜렸한 이름의 함수를 만들자

 

함수의 세부 구현으로 생성된 기능이 함수명을 통해 바로 파악할 수 읶게 해야한다.

>> 한 가지 일만 하는 명확한 이름의 함수를 만들자

>> 한 가지 기능만 하는 리액트 컴포넌트를 만드는 방법도 있다.

 

조건이 많아진다면 한글도 유용하다.

 

 - 추상화

 

로직에서 핵심개념 뽑아오기

 

프론트엔드 코드의 추상화 예시

컴포넌트

 

함수

 

 

상황에 따라 적절하게 추상화하면 된다.

 

추상화 수준이 섞여 있으면 코드 파악이 어렵다

 

>> 비슷한 수준의 추상화들로 변경

 

 

클린 코드를 하기 위한 액션 아이템

1. 담대하게 기존 코드 수정하기

2. 큰 그림 보는 연습하기 : 그 떄는 맞고 지금은 틀릴 수 있다.

3. 팀과 함께 공감대 형셩하기 : 명시적으로 이야기를 하는 시간이 필요

4. 문서로 적어보기 : 이 코드가 향후 어떤 점에서 위험할 수 있는지와 어떻게 개선할 수 있는 지 생각해보자

TDS : Toss Design System

- 토스 제품 구성에 공통적으로 사용하는 디자인 시스템  

- 보다 효율적으로, 아름답고 일관된 UI 개발

- 반복되는 코드를 작성하는 시간 절약

- View, 색상, 글꼴, 인터렉션과 애니메이션 등

별도 모듈로 관리하고 있기 때문에 다른 제품을 개발할 때도 쉽게 적용 가능

 

TDS를 구성하는 것들

- 컬러 & 리소스

Color

컬러 팔레트화 하여 사용 ex) 파란색 >> blue_진한정도표시

> 색상 코드를 직접 찍지 않고 이름으로 커뮤니케이션 가능하도록 관리

Day와 Night 모드 대응 

> 같은 이름의 색상을 night 리소스로 별도 관리

 

규칙화된 팔레트의 힘

- 토스팀에서 개발되는 모든 플랫폼 > 같은 TDS 색상을 바라보고 있음

> 서버로부터 UI를 그리기 위한 색상을 전달 받을때 Color Hex Code가 아닌 TDS 색상의 이름 내려받음

> 모두 공통된 이름을 기준으로 색상 파싱하여 적용 >> 다른 팀원과의 커뮤니케이션 증가와 색상 값의 자연스러운 최신화 가능

 

TDS 팔레트 색상 값 원격 서버에 존재 > 빌드 타임에 다운로드 받아 앱 리소스에 generate

 

Resources

토스 제품들의 이미지 리소스는 4가지로 구분됨

토스 리소스 센터에 정의

경우에 따라 벡터 이미지와 비트맵 이미지 혼용

- Icon

- Lottie

- Logo

- Illustration

 

로고와 일러스트 이미지 원형 그대로 사용

아이콘 로띠 이미지는 TDS에 정의된 이미지 리소스에 tint 사용하여 활용

 

 

- 스타일

컴포넌트화된 각종 스타일(UI에 활용되는 스타일 및 인터렉션까지 개별적인 컴포넌트처럼 사용)

 

TDS에서 Button. BottomSheet 등에서 원의 호로 처리하고 있는 둥근 모서리

> 베지어 곡선을 그려내는 방식으로 구현

 

*베지어 곡선 : 곡선으 최소 2개의 제어점 세트로 정의되며 두 개의 가상 선을 그리고 첫 번째 도우미 선의 시작점과 두 번째 도우미 선의 마지막 점으로 이동하는 가상의 세번째 섬을 따라가며 그어지는 곡선

 

TDS의 ScrollView 

어떤 View가 어떤 위치에 배치되어 있는지에 따라 상단과 하단의 Fading Edge를 다르게 적용해야 하는 일이 있음

(파란색 : Fading Edge 적용/ 붉은색 : 적용 x)

ScrollVIew 상속 받은 후 각 방향의 Fading Edge를 enum으로 받음 >> TDSScrollView

(기존의 동작하던 코드를 최대한 손대지 않고 문제를 해결하는 것을 중요시 여김 >> Custom Inflater 사용 > inflate 시점에 TDSScrollView로 대체 될 수 있도록 설계)

 

 

- 인터렉션

TDS가 유저에게 직접적으로 피드백을 주는 햅틱 피드백

햅틱 피드백

 

 

- 컴포넌트

UI 컴포넌트

택스트 이미지 등 여러 가지 작은 단위로 쪼개어 구성한 TDS 컴포넌트들을 연결하고 조합하여 만든 최종 결과

 

추가 요소 혹이니 기능이 필요할 경우 디자이너 개발자 구분 없이 자유롭게 추가 가능

단지 쌓아가는 것으로 옆의 디자인을 만들 수 있음

 

 

TDSL

 TDS 자체로 하나의 완성된 기능을 수행하기 때문에 DSL화해 간단하고 반복되는 UI를 구성한

+ Recent posts