Skip to content

Commit 45f4725

Browse files
Fix hydration error, remove prefetch helper (#2697)
* remove prefetch helper, co-locate queryclient creation * fix typo
1 parent 53a20f4 commit 45f4725

File tree

17 files changed

+257
-249
lines changed

17 files changed

+257
-249
lines changed

frontends/api/src/ssr/prefetch.ts

Lines changed: 0 additions & 31 deletions
This file was deleted.

frontends/api/src/ssr/serverQueryClient.ts

Lines changed: 0 additions & 76 deletions
This file was deleted.

frontends/main/src/app-pages/DashboardPage/CoursewareDisplay/EnrollmentDisplay.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ import { useQuery } from "@tanstack/react-query"
1414
import { userEnrollmentsToDashboardCourses } from "./transform"
1515
import { DashboardCard } from "./DashboardCard"
1616
import { DashboardCourse, EnrollmentStatus } from "./types"
17-
import { MaybeHasStatusAndDetail } from "@/app/getQueryClient"
17+
import type { AxiosError } from "axios"
1818

1919
const Wrapper = styled.div(({ theme }) => ({
2020
marginTop: "32px",
@@ -183,7 +183,7 @@ const EnrollmentDisplay = () => {
183183
...enrollmentQueries.courseRunEnrollmentsList(),
184184
select: userEnrollmentsToDashboardCourses,
185185
throwOnError: (error) => {
186-
const err = error as MaybeHasStatusAndDetail
186+
const err = error as AxiosError<{ detail?: string }>
187187
const status = err?.response?.status
188188
if (
189189
status === 403 &&

frontends/main/src/app/(products)/courses/[readable_id]/page.tsx

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,20 @@
11
import React from "react"
2-
import { HydrationBoundary } from "@tanstack/react-query"
2+
import { HydrationBoundary, dehydrate } from "@tanstack/react-query"
33
import { safeGenerateMetadata, standardizeMetadata } from "@/common/metadata"
4-
import { prefetch } from "api/ssr/prefetch"
54
import CoursePage from "@/app-pages/ProductPages/CoursePage"
65
import { notFound } from "next/navigation"
76
import { pagesQueries } from "api/mitxonline-hooks/pages"
87
import { coursesQueries } from "api/mitxonline-hooks/courses"
98
import { DEFAULT_RESOURCE_IMG } from "ol-utilities"
10-
import { getServerQueryClient } from "api/ssr/serverQueryClient"
9+
import { getQueryClient } from "@/app/getQueryClient"
1110

1211
export const generateMetadata = async (
1312
props: PageProps<"/courses/[readable_id]">,
1413
) => {
1514
const params = await props.params
1615

1716
return safeGenerateMetadata(async () => {
18-
const queryClient = getServerQueryClient()
17+
const queryClient = getQueryClient()
1918

2019
const data = await queryClient.fetchQuery(
2120
pagesQueries.coursePages(decodeURIComponent(params.readable_id)),
@@ -44,12 +43,17 @@ const Page: React.FC<PageProps<"/courses/[readable_id]">> = async (props) => {
4443
* fetching via client, and calling notFound() if data missing.
4544
* This approach blocked by wagtail api requiring auth.
4645
*/
47-
const { dehydratedState } = await prefetch([
48-
pagesQueries.coursePages(readableId),
49-
coursesQueries.coursesList({ readable_id: readableId }),
46+
const queryClient = getQueryClient()
47+
48+
await Promise.all([
49+
queryClient.prefetchQuery(pagesQueries.coursePages(readableId)),
50+
queryClient.prefetchQuery(
51+
coursesQueries.coursesList({ readable_id: readableId }),
52+
),
5053
])
54+
5155
return (
52-
<HydrationBoundary state={dehydratedState}>
56+
<HydrationBoundary state={dehydrate(queryClient)}>
5357
<CoursePage readableId={readableId} />
5458
</HydrationBoundary>
5559
)

frontends/main/src/app/(products)/programs/[readable_id]/page.tsx

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,20 @@
11
import React from "react"
2-
import { HydrationBoundary } from "@tanstack/react-query"
2+
import { HydrationBoundary, dehydrate } from "@tanstack/react-query"
33
import { safeGenerateMetadata, standardizeMetadata } from "@/common/metadata"
4-
import { prefetch } from "api/ssr/prefetch"
54
import ProgramPage from "@/app-pages/ProductPages/ProgramPage"
65
import { notFound } from "next/navigation"
76
import { pagesQueries } from "api/mitxonline-hooks/pages"
87
import { programsQueries } from "api/mitxonline-hooks/programs"
98
import { DEFAULT_RESOURCE_IMG } from "ol-utilities"
10-
import { getServerQueryClient } from "api/ssr/serverQueryClient"
9+
import { getQueryClient } from "@/app/getQueryClient"
1110

1211
export const generateMetadata = async (
1312
props: PageProps<"/programs/[readable_id]">,
1413
) => {
1514
const params = await props.params
1615

1716
return safeGenerateMetadata(async () => {
18-
const queryClient = getServerQueryClient()
17+
const queryClient = getQueryClient()
1918

2019
const data = await queryClient.fetchQuery(
2120
pagesQueries.programPages(decodeURIComponent(params.readable_id)),
@@ -46,12 +45,17 @@ const Page: React.FC<PageProps<"/programs/[readable_id]">> = async (props) => {
4645
* fetching via client, and calling notFound() if data missing.
4746
* This approach blocked by wagtail api requiring auth.
4847
*/
49-
const { dehydratedState } = await prefetch([
50-
pagesQueries.programPages(readableId),
51-
programsQueries.programsList({ readable_id: readableId }),
48+
const queryClient = getQueryClient()
49+
50+
await Promise.all([
51+
queryClient.prefetchQuery(pagesQueries.programPages(readableId)),
52+
queryClient.prefetchQuery(
53+
programsQueries.programsList({ readable_id: readableId }),
54+
),
5255
])
56+
5357
return (
54-
<HydrationBoundary state={dehydratedState}>
58+
<HydrationBoundary state={dehydrate(queryClient)}>
5559
<ProgramPage readableId={readableId} />
5660
</HydrationBoundary>
5761
)

frontends/main/src/app/c/[channelType]/[name]/page.tsx

Lines changed: 18 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import React from "react"
22
import ChannelPage from "@/app-pages/ChannelPage/ChannelPage"
3-
import { getServerQueryClient } from "api/ssr/serverQueryClient"
43
import { ChannelTypeEnum, UnitChannel } from "api/v0"
54
import {
65
FeaturedListOfferedByEnum,
@@ -9,8 +8,7 @@ import {
98
LearningResourceOfferorDetail,
109
} from "api"
1110
import { getMetadataAsync, safeGenerateMetadata } from "@/common/metadata"
12-
import { HydrationBoundary } from "@tanstack/react-query"
13-
import { prefetch } from "api/ssr/prefetch"
11+
import { HydrationBoundary, dehydrate } from "@tanstack/react-query"
1412
import {
1513
learningResourceQueries,
1614
offerorQueries,
@@ -25,6 +23,7 @@ import {
2523
} from "@/app-pages/ChannelPage/searchRequests"
2624
import { isInEnum } from "@/common/utils"
2725
import { notFound } from "next/navigation"
26+
import { getQueryClient } from "@/app/getQueryClient"
2827

2928
export async function generateMetadata({
3029
searchParams,
@@ -33,7 +32,7 @@ export async function generateMetadata({
3332
const { channelType, name } = await params
3433

3534
return safeGenerateMetadata(async () => {
36-
const queryClient = getServerQueryClient()
35+
const queryClient = getQueryClient()
3736

3837
const data = await queryClient.fetchQuery(
3938
channelQueries.detailByType(channelType, name),
@@ -58,16 +57,20 @@ const Page: React.FC<PageProps<"/c/[channelType]/[name]">> = async ({
5857

5958
const search = await searchParams
6059

61-
const { queryClient } = await prefetch([
62-
offerorQueries.list({}),
60+
const queryClient = getQueryClient()
61+
62+
await Promise.all([
63+
queryClient.prefetchQuery(offerorQueries.list({})),
6364
channelType === ChannelTypeEnum.Unit &&
64-
learningResourceQueries.featured({
65-
limit: 12,
66-
offered_by: [name as FeaturedListOfferedByEnum],
67-
}),
65+
queryClient.prefetchQuery(
66+
learningResourceQueries.featured({
67+
limit: 12,
68+
offered_by: [name as FeaturedListOfferedByEnum],
69+
}),
70+
),
6871
channelType === ChannelTypeEnum.Unit &&
69-
testimonialsQueries.list({ offerors: [name] }),
70-
channelQueries.detailByType(channelType, name),
72+
queryClient.prefetchQuery(testimonialsQueries.list({ offerors: [name] })),
73+
queryClient.prefetchQuery(channelQueries.detailByType(channelType, name)),
7174
])
7275

7376
const channel = queryClient.getQueryData<UnitChannel>(
@@ -102,13 +105,12 @@ const Page: React.FC<PageProps<"/c/[channelType]/[name]">> = async ({
102105
page: Number(search.page ?? 1),
103106
})
104107

105-
const { dehydratedState } = await prefetch(
106-
[learningResourceQueries.search(searchRequest as LRSearchRequest)],
107-
queryClient,
108+
await queryClient.prefetchQuery(
109+
learningResourceQueries.search(searchRequest as LRSearchRequest),
108110
)
109111

110112
return (
111-
<HydrationBoundary state={dehydratedState}>
113+
<HydrationBoundary state={dehydrate(queryClient)}>
112114
<ChannelPage />
113115
</HydrationBoundary>
114116
)

frontends/main/src/app/certificate/[certificateType]/[uuid]/page.tsx

Lines changed: 19 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,12 @@
11
import React from "react"
22
import { Metadata } from "next"
33
import CertificatePage from "@/app-pages/CertificatePage/CertificatePage"
4-
import { prefetch } from "api/ssr/prefetch"
54
import { certificateQueries } from "api/mitxonline-hooks/certificates"
6-
import { HydrationBoundary } from "@tanstack/react-query"
5+
import { HydrationBoundary, dehydrate } from "@tanstack/react-query"
76
import { isInEnum } from "@/common/utils"
87
import { notFound } from "next/navigation"
98
import { safeGenerateMetadata, standardizeMetadata } from "@/common/metadata"
10-
import { getServerQueryClient } from "api/ssr/serverQueryClient"
9+
import { getQueryClient } from "@/app/getQueryClient"
1110

1211
const { NEXT_PUBLIC_ORIGIN } = process.env
1312

@@ -24,7 +23,7 @@ export async function generateMetadata({
2423
return safeGenerateMetadata(async () => {
2524
let title, displayType, userName
2625

27-
const queryClient = getServerQueryClient()
26+
const queryClient = getQueryClient()
2827

2928
if (certificateType === CertificateType.Course) {
3029
const data = await queryClient.fetchQuery(
@@ -68,18 +67,24 @@ const Page: React.FC<
6867
notFound()
6968
}
7069

71-
const { dehydratedState } = await prefetch([
72-
certificateType === CertificateType.Course
73-
? certificateQueries.courseCertificatesRetrieve({
74-
cert_uuid: uuid,
75-
})
76-
: certificateQueries.programCertificatesRetrieve({
77-
cert_uuid: uuid,
78-
}),
79-
])
70+
const queryClient = getQueryClient()
71+
72+
if (certificateType === CertificateType.Course) {
73+
await queryClient.prefetchQuery(
74+
certificateQueries.courseCertificatesRetrieve({
75+
cert_uuid: uuid,
76+
}),
77+
)
78+
} else {
79+
await queryClient.prefetchQuery(
80+
certificateQueries.programCertificatesRetrieve({
81+
cert_uuid: uuid,
82+
}),
83+
)
84+
}
8085

8186
return (
82-
<HydrationBoundary state={dehydratedState}>
87+
<HydrationBoundary state={dehydrate(queryClient)}>
8388
<CertificatePage
8489
certificateType={certificateType}
8590
uuid={uuid}

frontends/main/src/app/certificate/[certificateType]/[uuid]/pdf/route.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import type { AxiosError } from "axios"
44
import type { NextRequest } from "next/server"
55
import * as Sentry from "@sentry/nextjs"
66
import moment from "moment"
7-
import { getServerQueryClient } from "api/ssr/serverQueryClient"
7+
import { getQueryClient } from "@/app/getQueryClient"
88
import { certificateQueries } from "api/mitxonline-hooks/certificates"
99
import {
1010
V2CourseRunCertificate,
@@ -562,7 +562,7 @@ type RouteContext = {
562562
export async function GET(req: NextRequest, ctx: RouteContext) {
563563
const { certificateType, uuid } = await ctx.params
564564

565-
const queryClient = getServerQueryClient()
565+
const queryClient = getQueryClient()
566566

567567
let pdfDoc
568568

0 commit comments

Comments
 (0)