React

타입스크립트 Generic

타입스크립트의 Generic 타입을 사용하면, 인자에 들어오는 타입을 그대로 사용 가능

타입스크립트의 여러 타입들

  1. 문자 타입
//                 들어오는타입    : 나가는타입 (들어오는 값도 문자열이고, 리턴하는값도 문자열이다)
const getString = (arg: string): string => {
  return arg;
};
const resultString = getString("안뇽");
console.log(resultString);
  1. 숫자 타입
const getNumber = (arg: number): number => {
  return arg;
};
const resultNumber = getNumber(12345);
console.log(resultNumber);
  1. 애니 타입
const getAny = (arg: any): any => {
  return arg;
};
const resultAny1 = getAny("철수");
const resultAny2 = getAny(123);
const resultAny3 = getAny(false);
console.log(resultAny1, resultAny2, resultAny3);
  1. 애니 타입2 (인자가 여러개일 경우)
const getAnys = (arg1: any, arg2: any, arg3: any): [any, any, any] => {
  return [arg3, arg2, arg1];
};
const resultAnys = getAnys("망고", 1111, true);
console.log(resultAnys);

5. 제네릭 타입 (들어온 타입을 그대로 사용하는 것)

//            <동일한 타입으로 묶을게>   이거랑 : 이거를
function getGeneric<MyType>(arg: MyType): MyType {
  return arg;
}
const aaa: string = "감자";
const bbb: number = 123;
const ccc: boolean = true;
const resultGeneric = getGeneric(aaa);
const resultGeneric2 = getGeneric(bbb);
const resultGeneric3 = getGeneric(ccc);
console.log(resultGeneric, resultGeneric2, resultGeneric3);

6. 제네릭 타입2 (4번을 제네릭 타입으로 바꾸기) => 더 안전한 코드 작성 가능

// 1) 함수형
// prettier-ignore
function getGenerics<MyType1,MyType2,MyType3>(arg1: MyType1, arg2: MyType2, arg3: MyType3): [MyType3, MyType2, MyType1] {
  return [arg3, arg2, arg1];
}
const resultGenerics = getGenerics("망고", 1111, true);
console.log(resultGenerics);

7. 제네릭 타입3(실무형) 축약1

// prettier-ignore
function getGenericsT<T1,T2,T3>(arg1: T1, arg2: T2, arg3: T3): [T3, T2, T1] {
  return [arg3, arg2, arg1];
}
const resultGenericsT = getGenericsT("망고", 1111, true);
console.log(resultGenericsT);
// 6번과 동일한 코드인데 타입 이름만 변경됨

8. 제네릭 타입3(실무형) 축약2
1) 함수형

// prettier-ignore
function getGenericsTUV<T,U,V>(arg1: T, arg2: U, arg3: V): [V, U, T] {
  return [arg3, arg2, arg1];
}
// prettier-ignore
const resultGenericsTUV = getGenericsTUV<string, number, boolean>("망고", 1111, true);
console.log(resultGenericsTUV);
// 6,7번과 동일한 코드인데 타입 이름만 변경됨

2) 화살표 함수형

const getGenericsArrow = <T, U, V>(arg1: T, arg2: U, arg3: V): [V, U, T] => {
  return [arg3, arg2, arg1];
};
// prettier-ignore
const resultGenericsArrow = getGenericsArrow<string, number, boolean>("망고", 1111, true);
console.log(resultGenericsArrow);

9. 제네릭 타입4 (useState)

const [AA, setAA] = useState<number>(111);

HOF 에서의 Generic

  1. HOF - 일반 타입
// function firstFunc1(arg1: string): (arg2: number) => [string, number] {
function firstFunc1(arg1: string) {
  return function secondFunc1(arg2: number): [string, number] {
    return [arg1, arg2];
  };
}
const resultFunc1 = firstFunc1("망고")(8);
console.log(resultFunc1);
  1. HOF - any 타입
function firstFunc2(arg1: any) {
  return function secondFunc2(arg2: any): [any, any] {
    return [arg1, arg2];
  };
}
const resultFunc2 = firstFunc2("망고")(8);
console.log(resultFunc2);

3. HOF - generic 타입
1) 함수형

function firstFunc3<T>(arg1: T) {
  return function secondFunc3<U>(arg2: U): [T, U] {
    return [arg1, arg2];
  };
}
const resultFunc3 = firstFunc3("망고")(8);
console.log(resultFunc3);
// any 처럼 모든 타입이 다 들어가지만, 훨씬 안전해짐 !

2) 화살표 함수형

// prettier-ignore
const firstFunc3Arrow = <T>(arg1: T) => <U>(arg2: U): [T, U] => {
    return [arg1, arg2];
};
const resultFuncArrow = firstFunc3Arrow("망고")(8);
console.log(resultFuncArrow);

HOF - generic 타입(컴포넌트에 응용해보기 - HOC)

// prettier-ignore
const withAuth = <C>(Component: C) => <P>(props: P): [C, P] => {
  return [Component, props];
};
const resultFuncWithAuth = withAuth("망고")({ qqq: "감자" });
//                              (컴포넌트자리)  (프룹스자리)
console.log(resultFuncWithAuth);

HOC - generic 타입

import { useRouter } from "next/router";
import { ComponentType, useEffect } from "react";

// prettier-ignore
export const withAuth = (Component: ComponentType) => <P extends {}>(props: P) => {
  const router = useRouter();

  useEffect(() => {
    if (!localStorage.getItem("accessToken")) {
      alert("로그인 후 이용 가능합니다!!!");
      router.push("/23-04-login-check");
    }
  }, []);

  return <Component {...props} />;
};

브라우저 저장소

브라우저에는 변수와 같이 저장할 수 있는 공간이 따로 존재.

변수에 저장해도 되는 것을 왜 굳이 브라우저에 저장하는 것일까?

변수에 저장한 데이터는 새로고침을 하게되면 사라지게 되지만 쿠키, 로컬스토리지, 세션스토리지 등은 새로고침을 하더라도 사라지지 않는다

쿠키 vs 로컬스토리지 vs 세션스토리지

쿠키는 로컬스토이지, 세션스토리지와 다르게 백엔드와 데이터를 주고받을 수 있음!

1. 쿠키

  • 만료 시간을 가지고 있음
  • 저장된 데이터가 Backend-API 요청시에 자동으로 함께 전송.
    Backend에서 데이터를 쿠키에 넣어서 API 응답시 Frontend에 전달할 수도 있음
  • httpOnly, secure등의 옵션을 설정해줄 수 있음
    • httpOnly : 브라우저에서 Javascript를 이용해 쿠키에 접근할 수 없습니다. 통신으로만 해당 데이터를 주고받을 수 있다
    • secure : https 통신시에만 해당 쿠키를 받아올 수 있다
  • 브라우저를 종료한 후 다시 들어와도 기록이 남아있음

2. 로컬스토리지

  • 데이터를 브라우저에 저장
  • 브라우저를 종료한 후 다시 들어와도 저장 기록이 남아있음

3. 세션스토리지

  • 데이터를 브라우저에 저장합
  • 브라우저를 종료할 때 삭제됨

저장소 저장 / 조회 실습

export default function BrowserStoragePage() {
  // 저장하는 함수 3개 만들기
  // 쿠키에 저장
  const onClickSaveCookie = () => {
    document.cookie = "AAA=철수";
    //                key , value에 값이 들어감
    document.cookie = "ZZZ=맹구";
  };

  // 로컬 스토리지에 저장
  const onClickSaveLocal = () => {
    localStorage.setItem("BBB", "영희");
  };

  // 세션 스토리지에 저장
  const onClickSaveSession = () => {
    sessionStorage.setItem("CCC", "훈이");
  };

  // 조회하는 함수 3개 만들기
  // 쿠키 조회
  const onClickLoadCookie = () => {
    const myCookie = document.cookie
      .split("; ")
      .filter((el) => el.startsWith("AAA="));
    console.log(myCookie);
  };

  // 로컬 스토리지 조회
  const onClickLoadLocal = () => {
    const BBB = localStorage.getItem("BBB");
    console.log(BBB);
  };

  // 세션 스토리지 조회
  const onClickLoadSession = () => {
    const CCC = sessionStorage.getItem("CCC");
    console.log(CCC);
  };

특정 객체에서 원본을 유지하고, 요소를 삭제하기

스프레드 연산자 이용

profile
어제보다 오늘 발전하는 프론트엔드 개발자

0개의 댓글