Next.js Discord

Discord Forum

Server Actions with formdata

Answered
The King posted this in #help-forum
Open in Discord
Avatar
Why can't I pass files that are in form data to server actions.
Another question is why can't I pass some objects from client to server components?
Answered by Double-striped Thick-knee
"use client";

import { uploadFile } from "@/actions/uploadFile";

export default function Page() {
    async function submit(e: any) {
        e.preventDefault();
        const input: HTMLInputElement = e.target[0] as any;
        const file: File = input.files?.item(0) as File;

        const form = new FormData();
        form.append("file", file);
        form.append("message", "Hello World");

        await uploadFile(form);
    }

    return (
        <form onSubmit={submit} className="p-5 flex flex-col gap-2 w-min">
            <input type="file" required />
            <button className="border rounded-md p-1" type="submit">
                Submit
            </button>
        </form>
    );
}
View full answer

32 Replies

Avatar
@The King Can you explain your trouble in more detail?
to answer your second question, server components can be only children of client component
to be more clear, client components can't include server components inside it
how would you like to pass object from client to server component?
Avatar
Image
@James4u Here you go
it should be a little bit space apart
Avatar
bump
Avatar
Double-striped Thick-knee
@The King is it solved?
Avatar
No
Still waiting on help
Avatar
Double-striped Thick-knee
I can make you a minimal demo if you want.
Avatar
Yes thank you
Avatar
Double-striped Thick-knee
"use client";

import { uploadFile } from "@/actions/uploadFile";

export default function Page() {
    async function submit(e: any) {
        e.preventDefault();
        const input: HTMLInputElement = e.target[0] as any;
        const file: File = input.files?.item(0) as File;

        const form = new FormData();
        form.append("file", file);
        form.append("message", "Hello World");

        await uploadFile(form);
    }

    return (
        <form onSubmit={submit} className="p-5 flex flex-col gap-2 w-min">
            <input type="file" required />
            <button className="border rounded-md p-1" type="submit">
                Submit
            </button>
        </form>
    );
}
Answer
Avatar
Double-striped Thick-knee
"use server";

export async function uploadFile(e: FormData) {
    console.log(e);
}
@The King
Avatar
Thank you so much
Another question I have is how can I secure them. Becuase I have this Sign-up form but my friend created a script to call the next action and spam it.
Would it be solved if I did export instead of export default?
Avatar
Bump
Avatar
Double-striped Thick-knee
nah, it's public forever. you gotta rate-limit the routes.
Avatar
Ah, so then what's the difference between import server-only and use server?
Avatar
Double-striped Thick-knee
"server-only" means they are only accessible in the server. whereas "use server" is accessible from client.
Avatar
And use server can access server only?
Ohh
So I can use that for api routes?
Avatar
Double-striped Thick-knee
you can export functions from a file with "use server" at the top of that file. these functions can be accessed from client components. you can see in this example. uploadFile function runs on the server even when called inside client component
basically next.js compiles those functions into fetch calls
Avatar
Ohh
Ok
Thank you
So much