如何在 Next.js 中的服务器端和客户端组件之间进行通信

问题描述 投票:0回答:1

我想制作一个交互式组件来更改我网站上的语言,并将该信息存储在 cookie 中,以便能够访问我的项目中的正确字典。然而,我遇到了一些问题,因为 Next 不允许服务器端组件的反应性挂钩,这是使用 cookie 所必需的,而且我无法将函数传递给客户端组件。我该怎么办?

服务器

    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();
      function handleLanguageChange(newLanguage: string) {
        cookieStore.set("lang", newLanguage);
      }
      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 onLanguageChange={handleLanguageChange} />
          </Flex>
        </header>
      );
    }

客户

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

    export default function LangFlag({
      onLanguageChange,
    }: {
      onLanguageChange: (newLanguage: string) => void;
    }) {
      const [lang, setLang] = useState("en");
      const [flag, setFlag] = useState(
        "img1"
      );
      const changeLang = () => {
        if (lang === "en") {
          setLang("se");
          setFlag(
            "img1="
          );
        } else {
          setLang("en");
          setFlag(
            "img2"
          );
        }
        onLanguageChange(lang);
      };
      return (
        <Box>
          <Image
            src={flag}
            alt={lang}
            sx={flagPictureStyle}
            onClick={changeLang}
          ></Image>
        </Box>
      );
    }

这会给出错误“事件处理程序无法传递给客户端组件道具。”

reactjs typescript next.js server client
1个回答
0
投票

尝试拆分组件并将标头保留在服务器端,例如:

头文件

//imports
export default function Header() {
  return (
    <header>
      <FlexWrapper />
    </header>
  );
}

FlexWrapper 文件

"use client";
// imports

export const FlexWrapper = () => {
  const cookieStore = cookies();
  function handleLanguageChange(newLanguage: string) {
    cookieStore.set("lang", newLanguage);
  }

  return (
    <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 onLanguageChange={handleLanguageChange} />
    </Flex>
  )
}

LangFlag 文件

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

export default function LangFlag({
  onLanguageChange,
}: {
  onLanguageChange: (newLanguage: string) => void;
}) {
  const [lang, setLang] = useState("en");
  const [flag, setFlag] = useState(
    "img1"
  );
  const changeLang = () => {
    if (lang === "en") {
      setLang("se");
      setFlag(
        "img1="
      );
    } else {
      setLang("en");
      setFlag(
        "img2"
      );
    }
    onLanguageChange(lang);
  };
  return (
    <Box>
      <Image
        src={flag}
        alt={lang}
        sx={flagPictureStyle}
        onClick={changeLang}
      ></Image>
    </Box>
  );
}
© www.soinside.com 2019 - 2024. All rights reserved.