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

Next.js服务端与客户端组件通信:语言切换Cookie存储问题

解决Next.js语言切换组件的Cookie操作与组件通信问题

问题原因

你遇到的报错「Event handlers cannot be passed to Client Component props.」是因为Next.js的服务端组件(Server Component)只能向客户端组件(Client Component)传递可序列化的props(如字符串、数字、普通对象),函数属于不可序列化类型,无法直接传递。另外,服务端的cookieStore是服务端环境专属API,不能在客户端调用,所以原来在服务端组件里定义的handleLanguageChange函数无法在客户端执行。

解决方案

把语言切换和Cookie操作的逻辑全部移到客户端组件中,服务端组件只负责传递初始的语言值(从服务端Cookie读取),避免跨组件传递函数。

修改后的服务端组件(Header)

import Link from "next/link";
import { Flex, Box } from "@chakra-ui/react";
import { boxStyles } from "../globalStyles";
import { cookies } from "next/headers";
import LangFlag from "./langFlag";

export default function Header() {
  const cookieStore = cookies();
  // 从服务端Cookie获取当前语言,默认值设为'en'
  const currentLang = cookieStore.get("lang")?.value || "en";

  return (
    <header>
      <Flex flexDirection="row">
        <Box sx={boxStyles}>
          <Link href="/">Home</Link>
        </Box>
        <Box sx={boxStyles}>
          <Link href="/answer">Answer</Link>
        </Box>
        <Box sx={boxStyles}>
          <Link href="/create">Create</Link>
        </Box>
        {/* 只传递可序列化的初始语言值,不再传函数 */}
        <LangFlag initialLang={currentLang} />
      </Flex>
    </header>
  );
}

修改后的客户端组件(LangFlag)

"use client";
import { Box, Image } from "@chakra-ui/react";
import { useState, useEffect } from "react";
import { flagPictureStyle } from "../globalStyles";

// 客户端操作Cookie的辅助函数
const setLangCookie = (lang: string) => {
  // 设置Cookie,有效期30天,路径覆盖全站
  document.cookie = `lang=${lang}; path=/; max-age=${30 * 24 * 60 * 60}; SameSite=Lax`;
};

const getLangCookie = () => {
  // 从客户端Cookie中读取语言值
  const langCookie = document.cookie.split("; ").find(item => item.startsWith("lang="));
  return langCookie ? langCookie.split("=")[1] : "";
};

export default function LangFlag({ initialLang }: { initialLang: string }) {
  // 初始化语言:优先取客户端Cookie,没有则用服务端传递的初始值
  const [lang, setLang] = useState(() => getLangCookie() || initialLang);
  // 根据语言设置对应的国旗图片
  const [flag, setFlag] = useState(() => lang === "en" ? "img1" : "img2");

  // 语言变化时同步更新Cookie
  useEffect(() => {
    setLangCookie(lang);
  }, [lang]);

  const changeLang = () => {
    const newLang = lang === "en" ? "se" : "en";
    setLang(newLang);
    setFlag(newLang === "en" ? "img1" : "img2");
  };

  return (
    <Box>
      <Image
        src={flag}
        alt={lang}
        sx={flagPictureStyle}
        onClick={changeLang}
      />
    </Box>
  );
}

关键修改点

  1. 组件通信规则适配:服务端组件仅传递可序列化的初始语言值,避免传递函数触发报错。
  2. Cookie操作客户端化:用document.cookie在客户端完成Cookie的读写,符合Next.js的环境限制。
  3. 状态一致性保障:初始化时优先读取客户端Cookie,确保服务端渲染和客户端交互的语言状态一致。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 22:16:36