[TIL] 1214

박재영·2020년 12월 14일
0

TIL

목록 보기
7/7

ApolloClient Local State management

redux 를 사용하지 않고 global state를 관리할 방법을 찾다가ApolloClient를 이용한 local state management를 알 게 되었다.

GraphQLServer와 동일하게 client에서도 cache를 사용해 관리하는 방법도 있고 ApolloClient 버전 3 부터 제공되는 Reactive variables 를 사용하는 방법도 있다.

1. Reactive variables

  • React의 useState를 사용하는 것처럼 값이 변경되었을 때 컴포넌트를 리랜더링할 수 있게 해준다.
// cache.js
import { makeVar } from "@apollo/client";

export const usersVar = makeVar([]);
// 함수처럼 호출
// 인자에 아무것도 넘기지 않으면 기존에 있던 값을 반환
const users = usersVar();

// 인자에 값을 넘기면 기존 값을 대체
const newUser = "mina";
usersVar([...usersVar(), newUser]);
// ReactiveVarExample.js
import React from "react";
import { useReactiveVar } from "@apollo/client";
import { usersVar } from "../apollo/cache";

export default function ReactiveVarExample() {
  // useReactiveVar로 usersVar를 넘겨야 변경사항을 감지하여 리랜더링해준다.
  const users = useReactiveVar(usersVar);

  return (
    <div>
      <h2>Use Reactive Variable</h2>
      <ul>
        {users.map((username, index) => (
          <li key={index}>{username}</li>
        ))}
      </ul>
    </div>
  );
}

2. Local Cache

  • GraphQL server 처럼 스키마(typeDefs)를 작성한다
  • useQuery로 동일하게 쿼리문을 넘겨서 작동한다, 이때 @client 를 붙여줘야 함!
// typeDefs.js
import { gql } from "@apollo/client";

export const typeDefs = gql`
  extend type Query {
    users: [User]!
  }

  extend type User {
    name: String!
  }
`;
// query.js
import { gql } from "@apollo/client";

export const GET_USERS = gql`
  query getUsers {
    users {
      name @client
    }
  }
`;
import { ApolloClient, InMemoryCache } from "@apollo/client";
import { typeDefs } from "./typeDefs";
import { GET_USERS } from "./query";

const cache = new InMemoryCache();

// 초기값 지정
cache.writeQuery({
  query: GET_USERS,
  data: {
    users: [],
  },
});

// client 전용 쿼리를 사용하기 위해 typeDefs 인자로 넘겨주기
export const client = new ApolloClient({
  uri: "https://48p1r2roz4.sse.codesandbox.io",
  cache,
  typeDefs,
});
const client = useApolloClient();
// 기존 데이터 불러오기
const data = client.readQuery({ query: GET_USERS });
// 새 데이터 추가하기
client.writeQuery({
  query: GET_USERS,
  data: {
    users: [...data.users, createUser(inputRef.current.value)],
  },
});

// __typename을 반드시 지정해야 에러가 나지 않는다.
// typeDefs에서 type을 찾을 때 __typename을 보기 때문
const createUser = (name) => {
  return {
    name,
    __typename: "user",
  };
};

0개의 댓글

관련 채용 정보