[refetchQueries] vs [apollo-cache-state Update]

송현섭 ·2023년 4월 21일
0

개별공부

목록 보기
25/44

refetch 의 단점


  • 기존에 사용하던 refetch는 사실 효율적인 방법이 아님

  • graphql 에서 useQuery( ) 를 사용해 data를 fetch 하면 해당 data는 cache-state 라는 저장소에 저장되는데, refetch를 사용하면 백엔드에서 새롭게 data를 받아와서 이를 다시 cache-state에 저장하기 때문에 비효율적임
    *data를 불러올 때 API요청 한 번, 이후 변경된 data를 refetch로 업데이트 시 또 한 번 API 요청이 들어가기에 효율적이지 못함!







apollo-cache-state 직접 업데이트 하기


  • 위이 비효율적인 방법을 해결하기 위해 cache-state를 직접 업데이트 하는 방식을 사용할 수 있음


//삭제 함수
  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를 업데이트] 하는 방식을 사용하는 게 더 유용!

profile
막 발걸음을 뗀 신입

0개의 댓글