1

Need help, NEXTJS 13 'app Dir'

How can I pass a function that is found on the Server Component to the Client Component?

I have Button which is a Client component and Another Server Component that wraps it. when The Button is Clicked I want execute the function passed down from Server Component. I don't want to change the Server Component to Client Component because it has large audio files and Images I don't want to render those components on client.

if there's any approach you've used to accomplish this I love to know.

When I try to pass down function from Server Component to Client I get this error.

client.js?7422:691 Uncaught Error: Functions cannot be passed directly to Client Components because they're not serializable.
  <... intent=... action={function} children=...>
  • 1
    Did you solve this error? I also get this error – Rahil Əliyev Mar 03 '23 at 13:12
  • It's actually cannot be achieved. in Nextjs 13 only serializable props can be passed from server to client component. https://beta.nextjs.org/docs/rendering/server-and-client-components#passing-props-from-server-to-client-components-serialization – Yonatan Dejene Mar 06 '23 at 05:15

1 Answers1

0

You can use server actions to pass async functions from server to client components while having them still be callable from client. (As of Mat 2023 Server Actions are an alpha feature in Next.js). If you aren't doing Server Mutations (Server Actions that mutates your data and calls redirect, revalidatePath, or revalidateTag), you can directly pass the function as a prop like any other function. For example:

export default function SearchBar() {
  async function action() {
    "use server";
    console.log("action");
    await new Promise((resolve) => setTimeout(resolve, 1000));
  }

  return (
    <div className="flex justify-center w-full h-full  items-center px-4 relative ">
          <ColorDot action={action} />
    </div>
  );
}

And on the client component:

"use client";
import React from "react";

interface ColorDotProps {
  action?: () => Promise<void>;
}

const ColorDot: React.FC<ColorDotProps> = ({ action }) => {
  const disabled = !action;
  return (
    <div
      onClick={async () => {
        disabled ? null : await action();
      }}
    >
      <button className="w-3 h-3 rounded-full bg-red-500" />
    </div>
  );
};

export default ColorDot;
  • "If you aren't doing Server Mutations (Server Actions that mutates your data and calls redirect, revalidatePath, or revalidateTag), you can directly pass the function as a prop like any other function" Why is this dependent on a mutation happening in the server action? – Florian Walther Jun 11 '23 at 10:18