기존에 사용하던 refetch는 사실 효율적인 방법이 아님
graphql 에서 useQuery( )
를 사용해 data를 fetch 하면 해당 data는 cache-state 라는 저장소에 저장되는데, refetch를 사용하면 백엔드에서 새롭게 data를 받아와서 이를 다시 cache-state에 저장하기 때문에 비효율적임
*data를 불러올 때 API요청 한 번, 이후 변경된 data를 refetch로 업데이트 시 또 한 번 API 요청이 들어가기에 효율적이지 못함!
//삭제 함수
const onClickDelete = (boardId: string) => () => {
void deleteBoard({
variables: { boardId },
update(cache, { data }) {
// 캐시를 수정한다는 뜻의 cache.modify
cache.modify({
// 캐시에있는 어떤 필드를 수정할 것 인지 key-value 형태로 적어줍니다.
fields: {
fetchBoards: (prev, { readField }) => {
const deletedId = data.deleteBoard; // 삭제된ID
const filteredPrev = prev.filter(
(el) => readField("_id", el) !== deletedId // el._id가 안되므로, readField를 사용해서 꺼내오기
);
return [...filteredPrev]; // 삭제된ID를 제외한 나머지 9개만 리턴
},
},
});
},
});
};
//등록 함수
const onClickCreate = () => {
void createBoard({
variables: {
createBoardInput: {
writer: "영희",
password: "1234",
title: "제목입니다~~",
contents: "내용입니다@@@",
},
},
update(cache, { data }) {
// 캐시를 수정한다는 뜻의 cache.modify
cache.modify({
// 캐시에있는 어떤 필드를 수정할 것 인지 key-value 형태로 적어줍니다.
fields: {
fetchBoards: (prev) => {
return [data.createBoard, ...prev];
},
},
});
},
});
};
mutation의 variables 다음 두 번째 인자에 update(cache, {data})
로 cache 와 data를 불러옴
*여기서 {data} 에는 API 요청으로 업데이트 된 결과가 담김
cache.modify
를 이용해 캐시를 수정할 수 있으며, 그 안에 fields key로 어떤 필드의 value를 수정할 것인지를 지정
이후 해당 field 에 익명함수를 지정하여 prev(이전 값)를 인자로 받아 저장된 캐시를 업데이트
*ex. 수정
(prev) => {return [data.createBoard, ...prev]} 로 이전 값과 추가된 data를 합해서 return
*ex. 삭제
(prev, { readField }) => {
const deletedId = data.deleteBoard; // 삭제된ID
const filteredPrev = prev.filter(
(el) => readField("_id", el) !== deletedId // el._id가 안되므로, readField를 사용해서 꺼내오기
);
return [...filteredPrev];
-삭제된 게시글 data와 Board의 모든 data를 비교해 filter로 삭제된 data만 제거
-이후 filter된 값을 return
이 때 el에 해당 field의 각 data 정보가 바로 담기지 않음 (Reference 객체에 담겨있기 때문)
prev 내부의 각 요소들은 실제 객체의 데이터가 담긴 게 아닌, 객체에 접근 가능한 key값들로 이루어진 참조이기에 직접 데이터 접근이 불가능 함
*따라서 [readField]를 사용해 직접 원하는 data를 불러와서, 지정해줘야 함
(위 예시코드에서는 filter의 el을 data안의 _id 값으로 지정해 줌)
refetchQueries vs apollo-cache-state
refetchQueries 나 apollo-cache-state 나 백엔드에서 받아온 data를 업데이트 하는 부분에 있어서는 같음
refetchQueries 는 아예 API 재요청으로 data를 다시 받아서 다시 global state에 저장하는 방식
apollo-cache-state 는 fetch 시 새로 갱신되어 저장되는 global state에서 직접 data의 값을 업데이트(수정)해 주는 방식
-작은 서비스에서는 [refetchQueries] 가 코드 가독성에서 더 좋기 때문에 오히려 더 유용함!
-다만 규모가 커지면 서버 부하가 발생할 수 있기에 [직접 cache를 업데이트] 하는 방식을 사용하는 게 더 유용!