Next.js Discord

Discord Forum

How to pass data down to children from a component

Unanswered
Sokoke posted this in #help-forum
Open in Discord
SokokeOP
I need a lot of help. I'm working on a library that allows you to format data like this:

export default function Page() {
    return (
        <Collection
            path="/posts"
            where={["content", "==", "test"]}
            render={(data) => (
                <div className="bg-zinc-100 rounded-lg p-4">
                    <pre className="font-medium">
                        {JSON.stringify(data, null, 2)}
                    </pre>
                </div>
            )}
        />
    );
}


export const Collection: React.FC<CollectionProps> = ({
    path,
    where,
    render,
    loadingSlot,
}) => {
    const { db } = useGlobalFirebase();

    if (db === null) {
        console.error("Firebase db context not found");
        return null;
    }

    const [data, loading] = useCollection<DocumentData[]>(db, path, where);

    if (loading) {
        return <>{loadingSlot || <div>Loading...</div>}</>;
    }

    if (!data) {
        return <div>No data found</div>;
    }

    return <>{render(data)}</>;
};


This works just fine in React, but when I go to Next with it, it breaks.

Error: Functions cannot be passed directly to Client Components unless you explicitly expose it by marking it with "use server". Or maybe you meant to call this function rather than return it.
  <... path="/posts" where={[...]} render={function render}>
                                          ^^^^^^^^^^^^^^^^^


I've tried everything and I don't know if this is even possible to have it work like this. Please help, lmfao

2 Replies

@Sokoke I need a lot of help. I'm working on a library that allows you to format data like this: jsx export default function Page() { return ( <Collection path="/posts" where={["content", "==", "test"]} render={(data) => ( <div className="bg-zinc-100 rounded-lg p-4"> <pre className="font-medium"> {JSON.stringify(data, null, 2)} </pre> </div> )} /> ); } jsx export const Collection: React.FC<CollectionProps> = ({ path, where, render, loadingSlot, }) => { const { db } = useGlobalFirebase(); if (db === null) { console.error("Firebase db context not found"); return null; } const [data, loading] = useCollection<DocumentData[]>(db, path, where); if (loading) { return <>{loadingSlot || <div>Loading...</div>}</>; } if (!data) { return <div>No data found</div>; } return <>{render(data)}</>; }; This works just fine in React, but when I go to Next with it, it breaks. Error: Functions cannot be passed directly to Client Components unless you explicitly expose it by marking it with "use server". Or maybe you meant to call this function rather than return it. <... path="/posts" where={[...]} render={function render}> ^^^^^^^^^^^^^^^^^ I've tried everything and I don't know if this is even possible to have it work like this. Please help, lmfao
Add a fragment to it like:
export default function Page() {
    return (
<>
        <Collection
            path="/posts"
            where={["content", "==", "test"]}
            render={(data) => (
                <div className="bg-zinc-100 rounded-lg p-4">
                    <pre className="font-medium">
                        {JSON.stringify(data, null, 2)}
                    </pre>
                </div>
            )}
        />
</>
    );
}
SokokeOP
that doesn't seem to work. i believe the issue is something to do with hte fact that the Collection component must 'use client', so it tells me:

Functions cannot be passed directly to Client Components unless you explicitly expose it by marking it with "use server". Or maybe you meant to call this function rather than return it.

i come from Svelte, and in Svelte you can do <Component let:content>{content}</Component> and render the content. kinda like using it as a function. what i want to do here is pass in my props like where and path and then return it and manipulate it or render it however i want.