type을 모를 땐, 개발자에게 안전하게 코딩하도록 유도하기위해 any 말고 unknown으로 설정하자
any는 실제로 함수 반환 시 어떤 타입인지에 대한 정보는 잃게 되어 string을 넣어도 any타입이 반환되는 반면, generic은 입력 값에 따라 내부 타입이 정의가 된다.
// 6. generic 응용
export function getGenericReverse<MyType1, MyType2, MyType3 >(arg1: MyType1, arg2: MyType2, arg3: MyType3): [MyType3,MyType2,MyType1] {
return [arg3, arg2, arg1]
}
const result6 = getGenericReverse("철수", "다람쥐초등학교", 8);
console.log(result6);
================================================================================
// 8. generic 응용 - 축약버전2
export function getGenericReverseTUV<T, U, V>(arg1: T, arg2: U, arg3: V): [V,U,T] {
return [arg3, arg2, arg1] 📌 📌 (매개변수) 앞 < >를 사용해 함수에 타입 변수를 추가해 직접 type을 만들어줄 수 있다
}
const result8 = getGenericReverseTUV("철수", "다람쥐초등학교", 8);
console.log(result8);
generic은 단일 타입이 아닌 다양한 타입에서 작동하게 작성할 수 있고 useState,useMutation 등을 만들어 사용할 경우에 자주 쓰인다.
useState를 만들건 아니지만, hoc에서는 적용할 수 있다.
함수에서 함수를 return하는 클로저에서 사용하는 generic
const aaa = <T>(arg1: T ) => <U>(arg2: U ): [ T, U ] => {
return (있을경우)
}
매개변수와 반환되는 형태가 컴포넌트라 Component부분은 ComponentType으로, props부분은 {}객체로 지정한다.
<P extends {}> 📌 뭔진모르지만 객체 타입이야~
return은 :
을 통해 return type을 지정해 줄 수 있다.
fuction aaa():string{
return “망고”
}
브라우저 저장소 3대장 😎
1. Cookie
2. Local-Storage
3. Session-Stroage
변수에 데이터를 넣어 두면 새로고침 시 저장된 데이터가 날아간다.accessToken, state 또한 새로고침 or 페이지 이동 시 초기화된다. HTML, CSS, JS 를 다시 다운로드 받아서 화면에 새로 그리기 때문인데, 데이터를 유지하기 위해선 브라우저 저장소에 저장해야한다.
🔥 각 브라우저 저장소의 특징이 다르기 때문에, 특성에 맞춰 3가지 중 잘 골라서 사용하자!
브라우저 종료 시 저장 정보가 사라진다
📌 setItem() .getItem() 사용
브라우저를 종료해도 영구 저장되어 사라지지 않는다 ➡️ 보안상 좋지않아, 주로 가벼운 정보를 저장한다
📌 setItem() .getItem() 사용
📌 refreshToken 배우기 전까지 임시사용했다
Backend-API 요청시, 저장된 데이터가 http 통신 header안에 담겨 자동으로 함께 (요청을 안했는데!) 보내진다.
장점 : 브라우저-백엔드 간에 데이터를 공유하고싶은게 있을 때 쿠키에 담아두면 자동으로 전송 가능하다
단점 : 너무 많은 데이터를 담아두면 시간이 오래 걸리고 효율성이 떨어지게된다. 만료 시간이 존재하기에 브라우저를 종료해도 만료시간까지 살아있어서 보안에 민감한 내용이면 피해야한다.
➡️ 보안에 중요한 내용을 주고받을때 옵션을 사용해서 http 통신으로만 주고받는다
➡️ secure: https, httpOnly: true
📌 document.cookie 사용
쿠키에 담긴 내용을 콘솔에 찍어보면, 하나의 문자열로 나타나는데 세미콜론 ;
을 기준으로 데이터가 나뉜다.
쿠키 데이터 가공법 🍪
1. 세미콜론을 기준으로 split
2. 필요한 내용의 key를 startWith로 찾아서 filter로 거르기
3. key-value 형태를 value만 남을 수 있게 replace
비회원으로 장바구니 담기 & 오늘 본 상품 리스트를 만들어보자 !
비회원 상태에서 로컬스토리지에 임시로 저장해 놓고, 나중에 로그인에 성공했을 때 미리 담아 놓은 장바구니를 api 요청을 통해 정보를 받아온다
const onClickBasket = (el) => () => {
localStorage.setItem("basket", el); ---> ❗️ object로 받아오기 때문에 JSON.stringify로 문자열 변환해야한다
};
⬇️
const onClickBasket = (el) => () => {
localStorage.setItem("basket", JSON.stringify(el));
};
JSON.stringyfy()
: 객체 -> 문자열
JSON.parse()
: 문자열 -> 객체
const onClickBasket = (el) => () => {
const { __typename, ...newEl } = el; ---> ❗️ 새로운 NewEl 선언, __typename은 지우자
localStorage.setItem("basket", JSON.stringify(newEl));
};
기존데이터 + new
1. 기존 데이터 가져와서 새로 선언 (baskets) ❗️❗️ 빈배열로 넣어줘야한다. 위랑 다름!const baskets = JSON.parse(localStorage.getItem("basket") || "[]") ---> ❗️ 기존 데이터 가져와서 배열로 바꿔주고 새로 선언 (없으면 빈값)
- 새로운 el 선언
const { __typename, ...newEl } = el; ---> ❗️ 필요없는 데이터 지우고 새로 선언
- 새로 선언된 baskets에 값 넣어주기
baskets.push(newEl);
- 가공된 데이터 넣어주기
localStorage.setItem("basket", JSON.stringify(baskets))
중복데이터 제거
1. basket에 담겨 있는 el._id (basektEl._id)와 클릭한 el._id가 같으면 임시저장소 temp에 담는다const temp = baskets.filter((basketEl) => basketEl._id === el._id);
- 임시저장소에 값이 들어오면 (길이가 1이면) return 처리
if (temp.length === 1) { Modal.error({ content: "이미 담은 상품입니다" }); return; }
- 뒷 내용 같음