Кеш клиента Apollo не работает в следующем. js - PullRequest
1 голос
/ 05 мая 2020

У меня одна проблема по следующей. js Разработка. home.tsx - это главная страница моего проекта.

  • home.tsx
const GET_POSTS = graphql`
  query posts($accountname: String!, $page: Int, $pathBuilder: any, $postsStatus: String) {
    posts(accountname: $accountname, page: $page, postsStatus: $postsStatus)
      @rest(type: "Post", pathBuilder: $pathBuilder) {
      post_id
      author
      voteStatus(accountname: $accountname) @client
      created_at
    }
  }
`;

interface Props {
  author: string;
}

const Home: NextPage<Props> = ({ author }) => {
  const { data, fetchMore, loading } = useQuery(GET_POSTS, {
    variables: {
      accountname: author,
      page: 1,
      postsStatus: 'home',
      pathBuilder: () => `posts/?Page=1&Limit=5&domainId=1`,
    },
  });

  const loadMorePosts = () => {
    fetchMore({
      variables: {
        page: page + 1,
        pathBuilder: () => `posts/?Page=${page + 1}&Limit=5&domainId=1`,
      },
      updateQuery: (previousResult, { fetchMoreResult }) => {
        if (!fetchMoreResult) {
          return previousResult;
        }
        setPage(page + 1);
        return Object.assign({}, previousResult, {
          posts: [...previousResult.posts, ...fetchMoreResult.posts],
        });
      },
    });
  };

  return (
    <div></div>
  );
};

interface Context extends NextPageContext {
  apolloClient: ApolloClient<NormalizedCacheObject>;
}

Home.getInitialProps = async (ctx: Context) => {
  const cookies = nextCookie(ctx);
  const author = cookies[encodeURIComponent(KARMA_AUTHOR)];
  ctx.apolloClient.writeData({
    data: {
      accountName: author,
    },
  });

  return {
    layoutConfig: { layout: labels.DEFAULT },
    meta: {
      title: 'Home',
    },
    author,
  };
};

export default withAuthSync(withApollo({ ssr: true })(Home));
  • withApollo.tsx
import { ApolloClient } from 'apollo-client';
import { withClientState } from 'apollo-link-state';
import serverFetch from 'node-fetch';
import graphql from 'graphql-tag';

const GET_PROFILE = graphql`
  query Profile($accountname: String!, $domainID: number) {
    profile(accountname: $accountname, domainID: $domainID)
      @rest(type: "Profile", path: "profile/{args.accountname}?domainID={args.domainID}") {
      author
      followers_count
      following_count
    }
  }
`;

const cache = new InMemoryCache({
  cacheRedirects: {
    Query: {
      post: (_, { post_id }, { getCacheKey }) => getCacheKey({ __typename: 'Post', post_id }),
    },
  },
  dataIdFromObject: object => {
    switch (object.__typename) {
      case 'Post':
        return getUniquePostId(object.post_id);
      case 'Comment':
        return getUniqueCommentId(object.cmmt_id);
      case 'Profile':
        return object.author;
      default:
        defaultDataIdFromObject(object);
    }
  },
});

const resolvers = {
  Post: {
    voteStatus: async ({ post_id }, args, { cache }, info) => {
      const { profile } = cache.readQuery({
        query: GET_PROFILE,
        variables: {
          accountname: args.accountname,
          domainID: 1,
        },
      });

      console.log(profile); // can't make console log because profile is not coming from readQuery
      if (profile) {
        return 1;
      } else {
        return 0;
      }
    },
  },
};

const stateLink = withClientState({
  cache,
  resolvers,
});

const restLink = new RestLink({
  uri: `${SERVER_URL}/`,
  serverFetch,
});

const createApolloClient = (initialState: NormalizedCacheObject, ctx: NextPageContext) => {
  return new ApolloClient({
    ssrMode: true,
    link: ApolloLink.from([stateLink, restLink]),
    cache,
  });
}

...
export const withApollo = ({ ssr = false } = {}) => (PageComponent: NextPage) => {
  const client = createApolloClient(initialState, ctx);

  ...
  return {
    ...pageProps,
    apolloState: apolloClient.cache.extract(),
    apolloClient: ctx.apolloClient,
  };
}

Если я сначала захожу на домашнюю страницу или обновляю sh домашнюю страницу, я не могу получить профиль в преобразователе, потому что cache.readQuery не работает. А также бесконечно вызывает api. Если я перейду на другую страницу и снова вернусь на домашнюю страницу, cache.readQuery будет работать и получить профиль и голосованиеStatus сообщения будут правильно. Кто-нибудь раньше сталкивался с этой проблемой? кто может решить эту проблему?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...