You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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),错误分支从未触发,所以这个拼写问题没暴露出来;切换为客户端组件后,可能某次请求进入了错误分支,或者构建阶段的代码检测更严格,才触发了这个错误。

此外,还有两个需要注意的细节:

  1. 客户端组件中使用fetch时,next: { tags: [...] }是无效配置——这是服务器组件/API路由专属的缓存策略,客户端fetch不会识别该选项,建议移除。
  2. 没必要把整个ReviewsPage改成客户端组件:Next.js支持混合渲染,只需将需要交互的子组件(比如Search)单独标记为use client,保留ReviewsPage作为服务器组件,这样既能实现交互需求,又能保留服务器端获取数据的性能优势。

修复步骤

  1. 修正拼写错误:将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();
};
  1. 优化组件结构(推荐):
    • 恢复page.jsx中的服务器组件配置,移除use client指令,重新添加metadata导出
    • 在需要使用useState的子组件(如Search)顶部添加use client指令

内容的提问来源于stack exchange,提问作者cts

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.27 19:34:59