{}
가 사용된 이유는 child의 data가 객체이기 때문, 만약 구조분해할당 시 데이터가 배열이라면 []
가 사용된다.const { data } = useQuery(FETCH_BOARDS);
이것은, uesQuery의 실행 결과 리턴 타입이 객체였단 것을 알 수 있다. //객체의 비구조화 할당
const {name, age, school} = child
const { data, loading } = useQuery(FETCH_BOARDS)
const [state, setState] = useState('');
state
의 초기값 설정setState
정리
구조분해할당에서 객체와 배열의 차이점, 객체의 구조분해할당은 선언부의 변수명이 객체의 key값이 할당되고, 배열은 변수명은 상관없지만 순서가 중요하다.
정리
객체에서 특정 값을 지우고 싶을때, delete를 사용하게 되면 원본의 값도 지우게 되어 좋지 않다.
따라서, 원본을 건드리지지 않기 위해 rest파라미터를 사용한다
const { _typename, ...newBasket } = basket
을 이용use
를 붙인 함수이다.그런데 Hook이 함수라면, custom hook역시 함수일텐데 일반함수와는 어떤 차이점이 있으며 비슷하면 그냥 함수를 쓰면 되지 굳이 왜 사용하는 것 일까?
router.push('/')
로 돌아가면 되어 쉬우나, 로그인 이전 마지막 페이지로 돌아가기 위해서는 globalState를 만들어놓고 로그인페이지 빼고 페이지 이동할 때마다 마지막 페이지를 저장해놓는다.// 1. 문자/ 숫자/ 불린 (primitive) 타입
const getPrimitive = (arg1: string,arg2: number,arg3: boolean): [boolean,number,string] => {
return [arg3, arg2, arg1];
}
const result = getPrimitive('철수', 123, true);
// 2. any 타입 => javascript와 같음
const getAny = (arg1: any,arg2: any,arg3: any): [any,any,any] => {
console.log(arg1 + 1000); // any는 아무거나 다 됨
return [arg3, arg2, arg1];
}
const result = getAny('철수', 123, true);
’알 수 없다, 모른다’ 라는 뜻으로, 개발자에게 주의를 주는 용도의 타입입니다. 타입이 지정되지 않았으므로 연산에 오류가 발생할 수 있음을 경고합니다.
’어떠한 것이든지, 누구든지’ 라는 뜻으로, 어떠한 타입이 입력되더라도 전부 허용하는 타입입니다. 요소에 any 타입을 부여할 경우 사실상 타입스크립트가 아닌 자바스크립트를 사용하는 것이나 마찬가지가 됩니다
// 3. unknown 타입
const getUnknown = (arg1: unknown ,arg2: unknown ,arg3: unknown ): [unknown ,unknown ,unknown ] => {
if(typeof arg1 === 'number') console.log(arg1 + 1000); // unknown은 사용시, 타입을 가정하여 사용해야 함
return [arg3, arg2, arg1];
}
// 4. generic 타입 - 1
function getGeneric< MyType1, MyType2, MyType3 >(arg1: MyType1 ,arg2: MyType2 ,arg3: MyType3 ): [ MyType3, MyType2, MyType1 ] {
return [arg3, arg2, arg1];
}
const result = getGeneric('철수', 123, true); // 타입 추론
const result2 = getGeneric<string,number,boolean>('철수',123,true); //타입 명시
타입을 추론
한 결과이다.const result = getGeneric('철수',123,true)
타입 명시
를 하려면 타입을 따로 작성하면 된다.const result = getGeneric<string,number,boolean>('철수',123,true)
// 5. generic 타입 - 2 변수명이므로 간소화
function getGeneric2< T1, T2, T3 >(arg1: T1 ,arg2: T2 ,arg3: T3 ): [ T3, T2, T1 ] {
return [arg3, arg2, arg1];
}
const result = getGeneric2('철수', 123, true);
// 6. generic 타입 - 3 더 간소화
function getGeneric3< T , U, V >(arg1: T ,arg2: U ,arg3: V ): [ V, U, T ] {
return [arg3, arg2, arg1];
}
const result = getGeneric3('철수', 123, true);
generic 타입은 왜 사용하는 것인가?
generic은 일반적으로 라이브러리를 가져다 사용하기 때문에 자주 사용하지는 않는다. useQuery, useMutation처럼 내가 만든 기능을 다른 사람에게 제공하는 경우 해당 기능에 들어오는 값의 타입을 예상할 수 없습니다. 이럴 때 Generic을 사용하면 들어오는 값의 타입에 따라 반환되는 값이나 컴포넌트의 타입이 결정되도록 할 수 있습니다. 즉,사용자 입장에서 타입 추론을 위해 generic을 사용한다.
// 6. generic 타입 - 4 화살표함수
const getGeneric4 = <T ,U , V>(arg1: T ,arg2: U ,arg3: V ): [V,U,T] => {
return [arg3, arg2, arg1];
}
const result = getGeneric4('철수', 123, true);
import { useRouter } from "next/router";
import { useEffect, ComponentType } from "react";
export const withAuth = (Component: ComponentType) => (props:any) => {
const router = useRouter();
useEffect(()=>{
if(!localStorage.getItem('accessToken')){
alert('로그인 후 이용가능합니다!');
void router.push('/23-03-login-check');
}
},[]);
return <Component {...props}/>
}
<P extends {}>(props: P)
정리
withAuth가 라이브러리와 유사한데, withAuth 사용시 다른 곳에서 import 하여 사용하는데, 어디서 어떻게 props를 무엇을 넣어 사용할지 모르는 상황이라 props 타입을 any로 할 수 밖에 없는데, any로 하게 되면 타입 추론이 불가하기 때문에 generic을 통하여 타입 명시해준다.
주로 라이브러리, 함수를 제공하는 입장에서 generic을 사용한다.