Next.js 14切换为客户端组件时出现response未定义错误求助
Next.js切换客户端组件后出现ReferenceError错误的原因与解决方法
问题背景
我有一个已实现的Next.js项目,其中ReviewsPage组件作为服务器组件可正常从Strapi CMS获取并展示最新6条评论,代码如下:
app > reviews > page.jsx
// IMPORTS export const metadata = { title: 'Reviews', }; const PAGE_SIZE = 6; export const ReviewsPage = async ({ searchParams }) => { // Extracting page parameter from searchParams const parsePageParam = (paramValue) => { if (paramValue) { const page = parseInt(paramValue); if (isFinite(page) && page > 0) { return page; } } return 1; }; const page = parsePageParam(searchParams.page); const { reviews, pageCount } = await getReviews(PAGE_SIZE, page); return ( <> <Heading>Reviews</Heading> <div className="flex justify-between pb-3"> <PaginationBar href="/reviews" page={page} pageCount={pageCount} /> <Search /> </div> <ul className="flex flex-row flex-wrap gap-3"> {reviews?.map((review, index) => ( <ReviewCard review={review} index={index} key={review?.slug} /> ))} </ul> </> ); }; export default ReviewsPage;
lib > reviews.js
import 'server-only'; import { marked } from 'marked'; import qs from 'qs'; export const CACHE_TAG_REVIEWS = 'reviews'; const CMS_URL = process.env.CMS_URL; export const getReviews = async (pageSize, page) => { const { data, meta } = await fetchReviews({ fields: ['slug', 'title', 'subtitle', 'publishedAt'], populate: { image: { fields: ['url'] } }, sort: ['publishedAt:desc'], pagination: { pageSize, page }, }); return { pageCount: meta?.pagination?.pageCount, reviews: data?.map(toReview), }; }; const fetchReviews = async (parameters) => { const url = `${CMS_URL}/api/reviews?` + qs.stringify(parameters, { encodeValuesOnly: true }); const response = await fetch(url, { next: { tags: [CACHE_TAG_REVIEWS], }, }); if (!response.ok) { throw new Error(`CMS returned ${repsonse.status} for ${url}`); } return await response.json(); }; const toReview = (item) => { const { attributes } = item; return { slug: attributes?.slug, title: attributes?.title, subtitle: attributes?.subtitle, date: attributes?.publishedAt.slice(0, 'yyyy-mm-dd'.length), image: CMS_URL + attributes?.image.data.attributes.url, }; };
为了扩展组件使用useState并引入客户端子组件,我做了以下修改:
- 在
page.jsx中添加use client指令 - 移除
metadata导出 - 删除
lib/reviews.js中的server-only导入
修改后出现构建错误:Uncaught (in promise) ReferenceError: repsonse is not defined at fetchReviews,同时打印的response日志显示请求返回了200状态。
错误原因
这个错误和切换客户端组件没有直接关联,纯粹是代码中的拼写失误:
在fetchReviews函数的错误处理逻辑里,你将变量response拼写成了repsonse(少写了一个s):
// 错误写法 throw new Error(`CMS returned ${repsonse.status} for ${url}`);
之前作为服务器组件时,可能因为请求始终成功(response.ok为true),错误分支从未触发,所以这个拼写问题没暴露出来;切换为客户端组件后,可能某次请求进入了错误分支,或者构建阶段的代码检测更严格,才触发了这个错误。
此外,还有两个需要注意的细节:
- 客户端组件中使用
fetch时,next: { tags: [...] }是无效配置——这是服务器组件/API路由专属的缓存策略,客户端fetch不会识别该选项,建议移除。 - 没必要把整个ReviewsPage改成客户端组件:Next.js支持混合渲染,只需将需要交互的子组件(比如
Search)单独标记为use client,保留ReviewsPage作为服务器组件,这样既能实现交互需求,又能保留服务器端获取数据的性能优势。
修复步骤
- 修正拼写错误:将
repsonse.status改为response.status,修正后的fetchReviews函数片段:
const fetchReviews = async (parameters) => { const url = `${CMS_URL}/api/reviews?` + qs.stringify(parameters, { encodeValuesOnly: true }); const response = await fetch(url, { // 客户端组件中移除无效的next缓存配置 // next: { tags: [CACHE_TAG_REVIEWS] }, // 可选:替换为客户端缓存策略 cache: 'force-cache' }); if (!response.ok) { throw new Error(`CMS returned ${response.status} for ${url}`); } return await response.json(); };
- 优化组件结构(推荐):
- 恢复
page.jsx中的服务器组件配置,移除use client指令,重新添加metadata导出 - 在需要使用
useState的子组件(如Search)顶部添加use client指令
- 恢复
内容的提问来源于stack exchange,提问作者cts
相关产品推荐
相关产品推荐

