[React] 카카오맵, cache-state

badassong·2022년 12월 13일
0

React

목록 보기
14/56
post-thumbnail

a태그와 라우터

a태그는 기존 HTML 페이지 이동방식 => 페이지를 다운로드 받아서 보여준다. 일반적인 속도.
router.push는 react/next에서의 페이지 이동방식 => 이미 있는 화면에서 추가 다운로드를 받아서 화면에 보여줌 => 속도가 매우 빠름!

카카오맵 연동 방법

  1. SPA - MPA 성능 차이 비교
  2. _app.tsx 에서 받아보기
  3. 제대로 페이지 이동 시 받고 다 받아지면 코드 실행하기
    참고 - https://apis.map.kakao.com/web/

1. SPA - MPA 성능 차이 비교

모바일앱은 전부 SPA(Single Page Application)이다.
그래서 굉장히 빠르다. 그래서 최근 나오는 웹서비스들도 SPA가 많다!

2. _app.tsx 에서 받아보기

_app.tsx에

<Head>
   <script
   type="text/javascript"
   src="//dapi.kakao.com/v2/maps/sdk.js?      appkey=f4c07c9738ac2386adb4ab9a6ae7740b"></script>
</Head> 

이 코드를 붙여넣으면 작동되긴 하지만 모든 페이지에서 다 카카오맵을 다운받기 때문에 비효율적이다.


앞으로 작업할 땐 Link 태그 사용한다!!

시멘틱 태그 사용의 장점

  1. 개발자들간에 커뮤니케이션 용이
  2. 검색엔진 최적화(SEO)

어쩔 수 없이 router.push를 써야하는 경우
=> 게시물 등록 후 리턴받은 아이디의 상세페이지로 이동할 때!


Cache-State 수정하기

나는 게시글을 등록하고 게시물 리스트를 다시 불러올 때 refetchqueries를 썼다. 하지만 refetchqueries는 그닥 효율적인 방법은 아니다. 왜냐하면 useQuery()는 수행 후 cache-state에 저장되는데 refetch를 사용하게 되면 새롭게 다시 받아오기때문에 비효율적인 구조가 되기 때문에 좋은 방법은 아니다.**

따라서 이제부터는 refetch를 하지 않고 apollo-cache-state를 직접 업데이트하는 방법을 사용해 볼 것 이다.

하지만 무조건 좋은 건 아님! cache-state는 큰 규모의 프로젝트에 적합하다!
오버엔지니어링을 주의하자!

import { useQuery, gql, useMutation } from "@apollo/client";
import { MouseEvent } from "react";
import {
  IQuery,
  IQueryFetchBoardsArgs,
} from "../../src/commons/types/generated/types";

const FETCH_BOARDS = gql`
  query fetchBoards($page: Int) {
    fetchBoards(page: $page) {
      _id
      writer
      title
      contents
    }
  }
`;

// 캐시에 저장되는 데이터와 요청 후 받아오는 값이 일치되어야 합니다.
const CREATE_BOARD = gql`
  mutation createBoard($createBoardInput: CreateBoardInput!) {
    createBoard(createBoardInput: $createBoardInput) {
      _id
      writer
      title
      contents
    }
  }
`;

const DELETE_BOARD = gql`
  mutation deleteBoard($boardId: ID!) {
    deleteBoard(boardId: $boardId)
  }
`;

export default function StaticRoutedPage() {
  const { data } = useQuery<Pick<IQuery, "fetchBoards">, IQueryFetchBoardsArgs>(
    FETCH_BOARDS
  );
  const [deleteBoard] = useMutation(DELETE_BOARD);
  const [createBoard] = useMutation(CREATE_BOARD);

//삭제 함수
  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];
            },
          },
        });
      },
    });
  };

  return (
    <>
      {data?.fetchBoards.map((el) => (
        <div key={el._id}>
          <span style={{ margin: "10px" }}>{el.writer}</span>
          <span style={{ margin: "10px" }}>{el.title}</span>
          <button onClick={onClickDelete(el._id)}>삭제하기</button>
        </div>
      ))}
      <button onClick={onClickCreate}>등록하기</button>
    </>
  );
}

캐시를 직접 수정하기 위해서는 update(){} 라는 기능을 이용하게 된다.
update 기능을 사용할때 파라미터로 데리고 온 cacheapollo-cache-state에 있는 global state 이다.
그리고 업데이트 된 결과 는 파리미터의 {data} 에 들어오게 된다.

fields의 prev와 return값

  • fields는 캐시에 있는 어떤 데이터를 수정할 것 인지를 알려줍니다.
  • fields 의 prev : 이전데이터를 불러온다!
  • fields의 return값 : 이전 데이터를 return 값으로 바꿔준다. 업데이트 된 결과가 {data} 이므로 결국 {data} 내부의 값이 된다!
profile
프론트엔드 대장이 되어보쟈

0개의 댓글