Apollo Client - React

먼저 React-Apollo란 무엇인지 알아보겠습니다.
Apollo는 React에서 Redux를 대체할 수 있는 GraphQL의 Client 중 하나입니다.
서버가 GraphQL로 구성되어 있을 때 가장 큰 효율을 발위하는 상태관리 플랫폼이면서 동시에 Client에서 GraphQL을 사용하여 데이터를 가져오기에 가장 좋은 라이브러리라고 생각됩니다.

JavaScript에서 오래된 형식인 Fetch로써 데이터를 가져오는 것이 아닌 Query문을 작성하고(GraphQL 서버에서 Query가 작성되어져 있다면 Apollo-client-tool(Chrome)을 통해 확인도 가능합니다.) 원하는 데이터만, 또는 데이터 전체를 받아 올 수 있는 장점이 있어 서버에서 필요없는 정보를 전송하지 않아도 되도록 클라이언트단에서 데이터 관리가 가능하도록 해줍니다.

만약 Redux를 사용하여 데이터 교환을 한다면 데이터를 요청하고 받기 까지의 과정은 실로 복잡합니다. 먼저 데이터를 요청하고 렌더링을 통하여 마운트 됨과 동시에 데이터 Fetch를 통해 데이터 구조화 작업을 하게 되고 데이터 구조화가 완료되면, action을 통해 fetch가 완료되었다고 전달 받습니다. 이 때 Redux는 Reducer를 통해 받은 데이터를 활용하여 뷰를 업데이트하는 구조를 가지고 있습니다.

위에서 간단하게 설명 드렸지만 구성까지 실로 복잡합니다. 이 때 React-Apollo를 쓰면 여러 과정을 단축시킬 수 있습니다. 그럼 React-Apollo를 쓰는 과정을 살펴 봅시다.

React-Apollo

먼저 Apollo-Boost로 Apollo를 실행합니다. Apollo-Boost란 apollot-cach / apollo-client / apollo link 등 여러 라이브러리를 모아서 Express에 매핑한 프레임워크라고 이해하면 됩니다.

Source 폴더 아래에 Apollo 폴더를 만들고 그 안에 Client.js 파일을 생성한 뒤 아래와 같이 코드를 기입합니다. src/Apollo/client.js

import ApolloClient from "apollo-boost";

export default new ApolloClient({
  uri: "http://localhost:4000",
});

노마드 코더의 인스타클론 강의 백엔드편을 완료한 후에 가능합니다. 여기서 Local Serve를 사용합니다. 로컬 서버를 실행합니다. 서버를 실행하면 아래와 같은 화면이 나오게 됩니다.

localhost4000실행

Apollo Provider와 Apollo Client

이제 Apollo Provider와 위에 Apollo-boost를 이용하여 작성한 코드를 연결하고 싶습니다. import { ApolloProvider } from "react-apollo-hooks"; index.js에서 </App> 컴포넌드를 <ApolloProvider>로 감싸 줍니다. App.js 파일에서 감싸주어도 되지만 index.js에서 App.js를 감싸는 이유는 나중에 Query를 실행해야되기 때문입니다. 코드는 다음과 같습니다. src/index.js

import React from "react";
import ReactDOM from "react-dom";
import App from "./Components/App";
import Client from "./Apollo/Client";
import { ApolloProvider } from "react-apollo-hooks";

ReactDOM.render(
  <ApolloProvider client={Client}><App /></ApolloProvider>,
  document.getElementById("root")
);

LocalState

Local State는 클라이언트에 없는 State입니다. 초기값을 정해주는 파일로 로컬 상태 관리할 때 사용합니다. 인스타그램 클론 코딩에서 Local State는 Authenticate(인증)이 되는지 아닌지만 할 것이기 때문에 복잡하지 않습니다. 따라서 Local State로 구성이 가능합니다.

정확히 이 구간에서는 이전 강의에서 구성했던 Router에서 로그인의 Boolean 값만 지정해주는 역할을 할 것입니다. 따라서 Default와 Resolve값이 있어야 합니다.

Defualt값은 로그인을 True 또는 False로 정의해주는 기능을 하며, resolver는 누군가 로그인하도록 도와주는 Mutation을 해야합니다. 따라서 Resolver에는 Arguments와 Token Cache 값이 필요합니다.

유저가 로그인하게 되면 유저에게 토큰을 부여하며 캐쉬를 써야합니다. 로그아웃하게 되었을 경우에는 토큰을 지우고 캐쉬를 초기화해야합니다. 모든 캐쉬를 지우기 위해서는 전체 페이지를 Reload하면 됩니다. src/Apollo/LocalState.js

export const defaults = {
  isLoggedIn: localStorage.getItem("token") !== null ? true : false
};

export const resolvers = {
  Mutation: {
    logUserIn: (_, { token }, { cache }) => {
      localStorage.setItem("token", token);
      cache.writeData({
        data: { isLoggedIn: true }
      });
      return null;
    },
    logUserOut: (_, __, { cache }) => {
      localStorage.removeItem("token");
      window.location.reload();
      return null;
    }
  }
};

client.js에 코드를 추가해줍니다. src/Apollo/client.js

import ApolloClient from "apollo-boost";

export default new ApolloClient({
  uri: "http://localhost:4000",
  clientState: {
    defaults,
    resolvers
  }
});

Apollo Client Developer Tools (Chrome)

위의 코드를 정상적으로 기입해두었다면 https://localhost:4000 으로 접속 시 아래와 같은 창이 뜨면 제대로 구성한 것입니다.

localhost4000실행

참고자료

Leave a comment