Server Actions with formdata
Answered
The King posted this in #help-forum
The KingOP
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?
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>
);
}
32 Replies
@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?
The KingOP
bump
Double-striped Thick-knee
@The King is it solved?
Still waiting on help
@The King Still waiting on help
Double-striped Thick-knee
I can make you a minimal demo if you want.
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
Double-striped Thick-knee
"use server";
export async function uploadFile(e: FormData) {
console.log(e);
}
@The King
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?
The KingOP
Bump
@The King Would it be solved if I did export instead of export default?
Double-striped Thick-knee
nah, it's public forever. you gotta rate-limit the routes.
@Double-striped Thick-knee nah, it's public forever. you gotta rate-limit the routes.
The KingOP
Ah, so then what's the difference between import server-only and use server?
@The King Ah, so then what's the difference between import server-only and use server?
Double-striped Thick-knee
"server-only" means they are only accessible in the server. whereas "use server" is accessible from client.
@Double-striped Thick-knee "server-only" means they are only accessible in the server. whereas "use server" is accessible from client.
The KingOP
And use server can access server only?
So I can use that for api routes?
@Double-striped Thick-knee ts
"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>
);
}
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 componentbasically next.js compiles those functions into fetch calls
Ok
Thank you
So much