最初にホームページにアクセスしたり、ホームページを更新したりすると、cache.readQueryが機能しないため、リゾルバーでプロファイルを取得できません。
また、APIを無限に呼び出します。
別のページに移動して再びホームページに戻ると、cache.readQueryが機能し、投稿のプロファイルとvoteStatusが正しく取得されます。
誰かが以前にこの問題に直面しましたか? home.tsxは私のプロジェクトのメインページです。
同様に、useQuery(@ apollo/react-hooks)はすべてのページで古いデータを取得します。
経験があれば私を助けてください。
...
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
_ 既存のデータを読み取れません-データを最初に照会する必要があります。
おそらく、切り替え中のページの1つがこのデータ(プロファイル)をクエリして、_<Home/>
_に戻ったときに使用できるようにします。
解決策-投稿をクエリする前にプロファイルをクエリします。
_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`,
},
});
_
skip
オプションは、条件が満たされるまでブロッククエリに使用されます。
ポストは、プロファイルデータを受信した後(およびキャッシュに書き込んだ後)にフェッチされます。このように、ローカルリゾルバー(voteStatus
)はcache.readQuery()
を使用して必要なデータにアクセスできます。