React 25강 - Day5
이번 시간에는 지금까지 배워온 것 중에서 궁금한 것들을 알아보는 시간을 가졌다.
기존의 graphql에서 refetch를 사용했는데 사실 refetch는 좋은 방식이 아니다.
refetch는 굉장히 쉬운 방식이었는데 성능적으로는 좋지 않기 때문에 이러한 문제점을
개선하는 방법을 알아보자.
목표
- 아하! 이제 const {} , const []의 원리와 차이를 알겠어!! => Destructing
- 객체에서 데이터를 삭제해보자!! => Rest-Parameter
- 뭐?! HOC는 원래 클래스 용이라구?! => custom-hooks
- refech는 사실 쉽지만 사용하기 불편해!!!~~ => writeQuery / readQuery
구조 분해 할당 이란?
const child = {
name: "철수",
age: 13,
school: "다람쥐 초등학교"
}
const name = child.name
const age = child.age
const school = child.school
먼저 객체를 선언하고 뽑아오는 기존의 방식은 child안에 값을 뽑아서 가져오는 방식이다.
하지만 이러한 방식이면 10개를 선언했다면 10개를 하나하나씩 선언해주어야 했다.
// 비구 조화 할당
const { name, age, school } = child
하지만 이렇게 child객체 안에있는 값들을 다시 객체안에 넣어주고 값을 :뽑아서 변수로 만들면 코드가 짧아진다.
굳이 3줄씩 하나하나 입력할 필요 없이 단 한줄로 선언이 가능하다.
이것도 언뜻보면 어떤거와 비슷하지 않은가??!!
const { data, loading } = useQuery(FETCH_BOARDS);
// 함수 = 실행후, return 값이 객체
// useQuery안에 객체에서 data와 loading을 뽑아온것이다.
useQuery() {
return {
data...,
loading...,
}
}
이것과 상당히 비슷하다. grahql에서 값을 선언할때 return 객체안에 data를 넣어주면 useQuery안에 객체에서
data와 lodaing을 뽑아온거나 마찬가지!!
const child = {
name: "철수",
age: 13,
school: "다람쥐 초등학교"
}
const name = child.name
const age = child.age
const school = child.school
// 비구 조화 할당
const { name, age, school } = child
그렇다면 사실상 이거는 일일이 불러온 const와 비구조화 할당을 이용해 짧게 줄인거와 동일한 것!!
const aaa = child;
// 객체 안을 지우고 aaa로 받은것과 똑같다.
const { name, age, school } = child
// 여기도 반드시 중괄호 X 도 된다.
// 이렇게 aaa라는 상자로 만들어서 aaa.name 이런 식으로 불러오면 된다.
const { aaa } = useQuery(FETCH_BOARDS);
비구조화를 배우고나서 보면 이렇게 data를 명시하지않고 aaa라는 상자로 만들어 aaa.name 이런식으로 불러오면
내가 정해준 데이터 명으로 값을 불러올 수 있다.
const classmates = ["철수", "영희", "훈이"];
const child1 = classmates[0];
const child2 = classmates[1];
const child3 = classmates[2];
// 이렇게 가능
// 3줄을 한줄로 쓸 수 있다.
// classmates 에서 뽑아주는데 이거를 child에 담아 통째로 담아주면
const [child1,child2,child3] = classmates;
const child = classmates;
// 배열을 특전 변수에 담아서 배열을 ㄹ불러오면 된다.
child[0]; // 철수
child[1]; // 영희
배열을 불러오는 방법도 객체 부분과 비슷하다. 기존에 하나하나씩 배열안에 숫자를 넣어 불러오는 것과는 달리
const 배열안에 값을 넣어서 classmates라는 상태값을 선언해주면 배열안에는 child1,2,3가 동시에 묶어주니
child라는 이름으로만 배열을 불러올 수 있다.
const classmates = ["철수", "영희", "훈이"];
const child1 = classmates[0];
const child2 = classmates[1];
const child3 = classmates[2];
// 이렇게 가능
// 3줄을 한줄로 쓸 수 있다.
// classmates 에서 뽑아주는데 이거를 child에 담아 통째로 담아주면
const [child1,child2,child3] = classmates;
const child = classmates;
// 배열을 특전 변수에 담아서 배열을 ㄹ불러오면 된다.
child[0]; // 철수
child[1]; // 영희
const {data, loading} = useQuery() // data 이름을 바꿀 수 없음
// 배열은 순서가 중요
// 바꿔도 상관 없다.
const classmates = ["철수", "영희" , "훈이"]
const [child1, child2, child3] = classmates;
// 아무이름 가능
const [aaa,setState] = useState
// Mutation도 동일
// 이름과 상관 없이 useMutation 0번째 것을 받음
const [dsadasd]= useMutation()
중요한 사실은 객체는 위치가 중요하고 배열은 순서가 중요하다.
RestParamter란?
const child = {
name: "철수",
age: 8,
school: "다람쥐 초등학교",
money: 2000,
hobby: "수영"
}
money 와 hooby 지우기
// 원본이 삭제됨
delete child.money
delete child.hobby
// Javascript에서는 원본이 같이 바뀌면 예기치 못한 에러가 발생할 수 있다.
RestParametre를 배우기전 우리가 객체안에 값을 지워보고 싶다면 ?!
delete를 이용하면 된다. delete를 이용하면 객체안에 값이 삭제가 되는데
단 원본이 삭제될뿐이다. Javascript에서는 원본이 같이 바뀌면 예기치 못한 에러가 발생할 수 있는데
이거를 해결해주는 방법은?
굳이 객체안에 값을 지우지 말고 우리가 원하는 값만 가져오면 되는데
그떄 쓰는게 restPrameter다.
// money와 hooby를 따로 할당 받고
// 나머지들 ...rest라는 이름에 몽땅 받아옴
const { money, hobby, ...rest } = child
const { money, hobby, myChild } = child;
이렇게 내가 제외하고 싶은게 money와 hobby라면 객체안에 두값을 넣거 ...rest로 선언해주면
그냥 rest안에는 제외한 객체 값이 들어가지 않는다.
커스텀 훅?!
import { useMoveToPage } from '../../src/components/commons/hooks/useMoveToPage';
export default function customHooksUseMoveToPage() {
const router = useRouter();
const onclickRoute = () => {
router.push('/');
}
const onclickMarket = () => {
rotuer.push('/market');
}
const onclickMyPage = () => {
router.push('/mypage');
}
return (
<div>
<div>커스텀훅 연습!! - 페이지 이동</div>
<button onClick={onclickRoute}>게시판 이동</button>
<button onClick={onclickMarket}>마켓 이동</button>
<button onClick={onclickMyPage}>마이페이지 이동</button>
</div>
);
}
우선 기존 방식의 구성을 보면 우리가 어느 버튼을 클릭하면 페이지로 넘어가는 코드를 구현할때
일일이 const로 onClick을 선언해서 router.push를 넣어줘야하는 귀찮음이 발생했다.
이것을 변수 하나로 구현하려면?
import { useRouter } from 'next/router';
import { useState } from 'react';
// union 타입
type IPage = '/board' | '/market' | '/mypage';
// // interface로 선언하면 두개의 동일한 이름일때 합쳐진다.
// // type은 그렇지 못함
// 선언 병합
// interface AAA {
// name: string;
// age: string;
// }
// interface AAA {
// school: string
// }
export function useMoveToPage() {
const router = useRouter();
const [visitedPage, setVisitedPage] = useState('/');
const moveToPage = (page: IPage) => () => {
router.push(page);
setVisitedPage(page);
console.log(page);
};
return {
visitedPage,
moveToPage,
};
}
대충 이런식으로 구현하면 되는데 하나하나 알아보자
// union 타입
type IPage = '/board' | '/market' | '/mypage';
먼저 Page에 대한 type을 선언해주고 그안에 | 를 사용해서 각각 이동할 페이지의 명을 넣어주면 된다.
export function useMoveToPage() {
const router = useRouter();
const [visitedPage, setVisitedPage] = useState('/');
const moveToPage = (page: IPage) => () => {
router.push(page);
setVisitedPage(page);
console.log(page);
};
return {
visitedPage,
moveToPage,
};
}
자 그러면 아까 선언한 타입을 moveToPage 함수에 () 안에 넣어서 router를 구현해주고 return으로 내보내주면
되는 간단한 방식이다.
import { useMoveToPage } from '../../src/components/commons/hooks/useMoveToPage';
export default function customHooksUseMoveToPage() {
const { moveToPage } = useMoveToPage();
return (
<div>
<div>커스텀훅 연습!! - 페이지 이동</div>
<button onClick={moveToPage('/board')}>게시판 이동</button>
<button onClick={moveToPage('/market')}>마켓 이동</button>
<button onClick={moveToPage('/mypage')}>마이페이지 이동</button>
</div>
);
}
그렇다면 moveToPage를 넣고 그안에 이동할 링크를 넣어주면 이렇게 짧게 변수 하나로 링크를 이동할 수 있다.
게시판 삭제하기 구현
// HOC에서는 가장 가까운곳에 async
const btnDelete = (boardId: string) => async () => {
// 삭제하기 로직
// catch는 기존 데이터 data는 삭제후 받은 데이터
await deleteBoard({
variables: { boardId },
update(cache, { data }) {
// 읽은 id와 deleteBoard와 다른것을 날려야함
const deletedId = data.deleteBoard;
cache.modify({
fields: {
// readField // field를 읽을 수 있는 함수
fetchBoards: (prev, { readField }) => {
// prev 안에 기존 30개 데이터가 존재 => 29개로 변경해야함
const filteredPrev = prev.filter(el => readField('_id', el) !== deletedId); // el._id 가 안되므로 readField를 사용
return [...filteredPrev];
},
},
});
},
});
};
데이터를 삭제하는 방식에는 먼저 삭제후 borad가 업데이트 되야 하니 update를 선언해주고 그안에 cache값과
data 값을 넣어줘야 한다.
그다음 삭제된 Id가 data안에 삭제한 board가 되야한다.
삭제가되고 보드가 수정되야하니 cache가 수정되도록 modify를 넣어서 fileds안에 fields를 읽을 수 있는 함수를
넣어준다.
그다음 이전 보드 페이지에서 만약 30개의 보드판이 있다면 30개에서 29개로 변경해야하니
fileter를 사용해서 이전 게시판을 삭제가 된 게시판 글이 되지않도록 선언해준다.
'etc. > TIL' 카테고리의 다른 글
[TIL] 2022년 02월 18일 - 쿠키와 로컬 세션 스토리지 , 장바구니 Basket (0) | 2022.02.18 |
---|---|
[TIL] 2022년 02월 16일 - 로그인 Validataion (0) | 2022.02.16 |
[TIL] 2022년 02월 15일 - withAuth와 SessionStorage / Cookie (0) | 2022.02.15 |