SSR useQuery Breaking Page Transition
Technically using an infinite query, but I have an array of
Posts
that I'm prefetching, but when I use a next.js Link
I get an undefined error during the transition1 Reply
// Home (/)
// Only loads the first 10 posts for the query limit
const Home = () => {
const { data } = trpc.posts.posts.useQuery({});
const { posts } = data!; // prefetched, so should have a result
return (
<nav>
<Link href="/posts">Posts</Link>
{posts.map((post) => <Link key={post.id} href={`/posts/${post.id}`}>{post.title}</Link>)}
</nav>
);
};
export const getServerSideProps = async (ctx) => {
const ssr = ssrHelper(ctx);
await ssr.posts.posts.prefetch({});
return {
props: {
trpcState: ssr.dehydrate();
}
}
}
// Home (/)
// Only loads the first 10 posts for the query limit
const Home = () => {
const { data } = trpc.posts.posts.useQuery({});
const { posts } = data!; // prefetched, so should have a result
return (
<nav>
<Link href="/posts">Posts</Link>
{posts.map((post) => <Link key={post.id} href={`/posts/${post.id}`}>{post.title}</Link>)}
</nav>
);
};
export const getServerSideProps = async (ctx) => {
const ssr = ssrHelper(ctx);
await ssr.posts.posts.prefetch({});
return {
props: {
trpcState: ssr.dehydrate();
}
}
}
Unhandled Runtime Error
TypeError: Cannot read properties of undefined (reading 'map')
<nav>
<Link href="/posts">Posts</Link>
{posts.map((post) => <Link key={post.id} href={`/posts/${post.id}`}>{post.title}</Link>)}
^
Unhandled Runtime Error
TypeError: Cannot read properties of undefined (reading 'map')
<nav>
<Link href="/posts">Posts</Link>
{posts.map((post) => <Link key={post.id} href={`/posts/${post.id}`}>{post.title}</Link>)}
^
/posts
and /posts/[postId]
(I use the home page to grab the top 10 posts, while the /posts uses a cursor based pagination
// /posts
const Posts: NextPage = () => {
const router = useRouter();
const { data } = trpc.posts.posts.useInfiniteQuery({}, { getNextPageParam: (lastPage) => lastPage.nextCursor });
return (
<>
<h1>Posts</h1>
<nav>
{data?.pages.map((page) => page.posts.map((post) => <Link key={post.id} href={`${router.asPath}/${post.id}`}>{post.title}</Link>))}
</nav>
</>
);
};
export default Posts;
export const getServerSideProps: GetServerSideProps = async (ctx) => {
const ssr = ssrHelper(ctx);
await ssr.posts.posts.prefetchInfinite({});
return {
props: {
trpcState: ssr.dehydrate(),
},
};
};
// /posts
const Posts: NextPage = () => {
const router = useRouter();
const { data } = trpc.posts.posts.useInfiniteQuery({}, { getNextPageParam: (lastPage) => lastPage.nextCursor });
return (
<>
<h1>Posts</h1>
<nav>
{data?.pages.map((page) => page.posts.map((post) => <Link key={post.id} href={`${router.asPath}/${post.id}`}>{post.title}</Link>))}
</nav>
</>
);
};
export default Posts;
export const getServerSideProps: GetServerSideProps = async (ctx) => {
const ssr = ssrHelper(ctx);
await ssr.posts.posts.prefetchInfinite({});
return {
props: {
trpcState: ssr.dehydrate(),
},
};
};
// /posts/[postId]
export type PostQuery = { postId: string };
const Post: NextPage = () => {
const router = useRouter();
const { postId } = router.query as PostQuery;
const { data: postData } = trpc.posts.post.useQuery(postId);
const post = postdData!;
const { data: commentsData } = trpc.posts.comments.comments.useInfiniteQuery({ postId }, { getNextPageParam: (lastPage) => lastPage.nextCursor });
const { pages } = commentsData!;
return (
<>
<h1>
Post
{' : '}
{post.title}
{' : '}
{post.id}
</h1>
{pages.map((page) => page.comments.map((comment) => (
<Link key={comment.id} href={`${router.asPath}/comments/${comment.id}`}>{comment.id}</Link>
)))}
</>
);
};
export default Post;
export const getServerSideProps: GetServerSideProps = async (ctx) => {
const { postId } = ctx.query as PostQuery;
const ssr = ssrHelper(ctx);
if (!await ssr.posts.post.fetch(postId)) {
return {
notFound: true,
};
}
await ssr.posts.comments.comments.prefetchInfinite({ postId });
return {
props: {
trpcState: ssr.dehydrate(),
},
};
};
// /posts/[postId]
export type PostQuery = { postId: string };
const Post: NextPage = () => {
const router = useRouter();
const { postId } = router.query as PostQuery;
const { data: postData } = trpc.posts.post.useQuery(postId);
const post = postdData!;
const { data: commentsData } = trpc.posts.comments.comments.useInfiniteQuery({ postId }, { getNextPageParam: (lastPage) => lastPage.nextCursor });
const { pages } = commentsData!;
return (
<>
<h1>
Post
{' : '}
{post.title}
{' : '}
{post.id}
</h1>
{pages.map((page) => page.comments.map((comment) => (
<Link key={comment.id} href={`${router.asPath}/comments/${comment.id}`}>{comment.id}</Link>
)))}
</>
);
};
export default Post;
export const getServerSideProps: GetServerSideProps = async (ctx) => {
const { postId } = ctx.query as PostQuery;
const ssr = ssrHelper(ctx);
if (!await ssr.posts.post.fetch(postId)) {
return {
notFound: true,
};
}
await ssr.posts.comments.comments.prefetchInfinite({ postId });
return {
props: {
trpcState: ssr.dehydrate(),
},
};
};
/posts
link does something and kills my page transition?
May be because of the caching / batching and how I'm treating an infinite query as a regular one on home but as a proper infinite on posts?