Apollo客户端graphql localstate管理设置

时间:2020-06-26 11:52:08

标签: graphql next.js apollo apollo-client apollo-server

我坐了2天,试图使设置正确。我的目标是将Next.js与ApolloGraphQl一起用于数据库请求以及本地状态管理处理。

我的问题是本地状态管理的设置。不知道为什么我无法正确使它工作。我希望你能帮助我。

我使用以下仓库在github上推送了项目的实际状态:

https://github.com/Maetes/apollo-next-local

更新:

当我只是调用缓存对象本身时,查询和更改状态是很好的,所以一切都很好。但是,当我尝试触发解析器时,什么也没有发生。我不喜欢Apollo客户端看不到typedef和解析器。

这是我在客户端初始化中使用的Apollo Hook:

import { IncomingMessage, ServerResponse } from 'http';
import { useMemo } from 'react';
import { ApolloClient } from 'apollo-client';
import { InMemoryCache, NormalizedCacheObject } from 'apollo-cache-inmemory';
import { resolvers } from './localResolvers';
import { typeDefs } from './localTypeDefs';
import {
  CREATE_USER,
  GET_CURRENT_USER,
  SET_CURRENT_USER,
  ALL_USERS,
} from './localDocuments';

let apolloClient: ApolloClient<NormalizedCacheObject> | undefined;

export type ResolverContext = {
  req?: IncomingMessage;
  res?: ServerResponse;
};

function createIsomorphLink(context: ResolverContext = {}) {
  if (typeof window === 'undefined') {
    const { SchemaLink } = require('apollo-link-schema');
    const { schema } = require('../pages/api/index');
    return new SchemaLink({ schema, context });
  } else {
    const { HttpLink } = require('apollo-link-http');
    return new HttpLink({
      uri: 'http://localhost:3000/api',
      credentials: 'same-origin',
    });
  }
}

function createApolloClient(context?: ResolverContext) {
  let cache = new InMemoryCache();
  cache.writeData({
    data: {
      currentUser: {
        __typename: 'CurrentUser',
        email: '',
        nachname: '',
        title: '',
        id: '',
      },
    },
  });

  let client = new ApolloClient({
    ssrMode: typeof window === 'undefined',
    link: createIsomorphLink(context),
    cache: cache,
    typeDefs,
    resolvers,
  });
  // client.writeData({
  //   data: {
  //     currentUser: {
  //       __typename: 'CurrentUser',
  //       email: '',
  //       nachname: '',
  //       title: '',
  //       id: '',
  //     },
  //   },
  // });
  return client;
}

export function initializeApollo(
  initialState: any = null,
  // Pages with Next.js data fetching methods, like `getStaticProps`, can send
  // a custom context which will be used by `SchemaLink` to server render pages
  context?: ResolverContext
) {
  const _apolloClient = apolloClient ?? createApolloClient(context);

  // If your page has Next.js data fetching methods that use Apollo Client, the initial state
  // get hydrated here
  if (initialState) {
    _apolloClient.cache.restore(initialState);
  }
  // For SSG and SSR always create a new Apollo Client
  if (typeof window === 'undefined') return _apolloClient;
  // Create the Apollo Client once in the client
  if (!apolloClient) apolloClient = _apolloClient;

  return _apolloClient;
}

export function useApollo(initialState: any) {
  const store = useMemo(() => initializeApollo(initialState), [initialState]);
  return store;
}

这是我的typedef文件:

从“ graphql-tag”导入gql;

export const typeDefs = gql`
  extend type Query {
    getCurrentUser: CurrentUser!
  }

  type CurrentUser {
    email: String!
    nachname: String!
    title: String!
    id: ID!
    __typename: String!
  }

  extend type Mutation {
    setCurrentUser(
      email: String!
      nachname: String!
      title: String!
      id: ID!
    ): CurrentUser!
  }
`;

这是我的解析器:

import { InMemoryCache } from 'apollo-cache-inmemory';
import { GET_CURRENT_USER } from './localDocuments';

export const resolvers = {
  CurrentUser: {
    currentUser: (_: {}, { cache }: { cache: InMemoryCache }) => {
      console.log('Resolver Query triggered');
      // const { user }: any = cache.readQuery({
      //   query: GET_CURRENT_USER,
      // });
      const data: any = {};
      data.__typename = 'CurrentUser';
      return data;
    },
    getCurrentUser: (_: {}, { cache }: { cache: InMemoryCache }) => {
      console.log('Resolver Query triggered');
      // const { user }: any = cache.readQuery({
      //   query: GET_CURRENT_USER,
      // });
      const data: any = {};
      data.__typename = 'CurrentUser';
      return data;
    },
  },

  Query: {
    getCurrentUser: (_: {}, { cache }: { cache: InMemoryCache }) => {
      console.log('Resolver Query triggered');
      // const { user }: any = cache.readQuery({
      //   query: GET_CURRENT_USER,
      // });
      const data: any = {};
      data.__typename = 'CurrentUser';
      return data;
    },
    currentUser: (_: {}, { cache }: { cache: InMemoryCache }) => {
      console.log('Resolver Query triggered');
      // const { user }: any = cache.readQuery({
      //   query: GET_CURRENT_USER,
      // });
      const data: any = {};
      data.__typename = 'CurrentUser';
      return data;
    },
  },
  Mutation: {
    setCurrentUser: (
      _: {},
      variables: any,
      { cache }: { cache: InMemoryCache }
    ) => {
      const { currentUser }: any = cache.readQuery({ query: GET_CURRENT_USER });
      console.log('mutationResolver Triggered');
      console.log(
        'olduser',
        currentUser.email,
        currentUser.nachname,
        currentUser.title
      );

      const newUser = {
        email: variables.email,
        title: variables.title,
        nachname: variables.nachname,
        __typename: 'CurrentUser',
      };

      console.log('newUser', newUser);
      const erg = cache.writeQuery({
        query: GET_CURRENT_USER,
        data: newUser,
      });
      return newUser;
    },
  },
};

最后确定我的文档文件以供个人输入。请注意,当我将“ getCurrentUser”更改为“ currentUser”时,在GetCurrentUserQuery查询中一切正常,原因是阿波罗将原始对象本身作为目标。

import gql from 'graphql-tag';

//Server
export const ALL_USERS = gql`
  query allUsersQuery {
    allUsers {
      title
      nachname
      email
      id
      __typename
    }
  }
`;

//client
export const GET_CURRENT_USER = gql`
  query GetCurrentUserQuery {
    getCurrentUser @client(always: true) {
      email
      nachname
      title
      __typename
    }
  }
`;

//Client
export const SET_CURRENT_USER = gql`
  mutation SetCurrentUserMutation(
    $email: String!
    $nachname: String!
    $title: String!
    $id: String!
  ) {
    setCurrentUser(email: $email, nachname: $nachname, title: $title) @client {
      email
      title
      nachname
      id
      __typename
    }
  }
`;

//Server
export const CREATE_USER = gql`
  mutation CreateUserMutation(
    $email: String!
    $nachname: String!
    $title: String!
    $password: String!
  ) {
    createUser(
      email: $email
      nachname: $nachname
      title: $title
      password: $password
    ) {
      __typename
      email
      nachname
      title
      password
      id
    }
  }
`;

0 个答案:

没有答案