How to communicate between a server side and client side component in Next.js

25 Views Asked by At

I want to make an interactive component for changing the languages on my website, and storing that information in cookies to be able to access the right dictionary in my project. However I am having some issues since Next doesn't allow reactive hooks for server side components, which is needed for using cookies, and I can't pass a function to my client side component. What should I do?

Server

    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>
      );
    }

Client

    "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>
      );
    }

This gives the error that "Event handlers cannot be passed to Client Component props."

1

There are 1 best solutions below

0
Reubert Barbosa On

Try to split the components and keep the Header on the server side like:

Header file

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

FlexWrapper file

"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 file

"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>
  );
}