Si je visite d'abord la page d'accueil ou actualise la page d'accueil, je ne peux pas obtenir de profil dans le résolveur car cache.readQuery ne fonctionne pas.
Ainsi qu'il appelle l'API à l'infini.
Si je passe à une autre page et que je reviens à la page d'accueil, cache.readQuery fonctionne et obtient le profil et le voteStatus du message correctement.
Quelqu'un a-t-il déjà fait face à ce problème? home.tsx est la page principale de mon projet.
De plus, useQuery (@ apollo/react-hooks) récupère les anciennes données sur chaque page.
Veuillez m'aider si vous avez des expériences.
...
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));
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,
};
}
cache.readQuery
impossible de lire les données non existantes - les données doivent d'abord être interrogées.
Probablement l'une des pages que vous changez interroge ces données (profil) les rendant disponibles lorsque vous revenez à <Home/>
.
Solution - recherchez le profil avant d'interroger les messages:
const Home: NextPage<Props> = ({ author }) => {
const { data: dataProfile, error: errorProfile, loading: loadingProfile } = useQuery(GET_PROFILE);
const { data, fetchMore, loading } = useQuery(GET_POSTS, {
skip: !dataProfile,
variables: {
accountname: author,
page: 1,
postsStatus: 'home',
pathBuilder: () => `posts/?Page=1&Limit=5&domainId=1`,
},
});
L'option skip
est utilisée pour la requête de bloc jusqu'à ce que la condition soit remplie.
Les publications sont récupérées après avoir reçu les données de profil (et les avoir écrites dans le cache). De cette façon, le résolveur local (voteStatus
) peut utiliser cache.readQuery()
pour accéder aux données requises.