Replies: 16 comments 27 replies
-
Code example? Forms have a reset method, or you could alternatively have a button with type "reset", but without a code example, it is a bit hard to guide you in the right direction. |
Beta Was this translation helpful? Give feedback.
-
Trying to figure out the same thing and not finding anything in the docs. There's no reset method on FormData at the moment. Using the latest version of next (currently 14.0.3).
|
Beta Was this translation helpful? Give feedback.
-
Any new things anybody found here? I want to be able to reset the form in my server component. |
Beta Was this translation helpful? Give feedback.
-
Nevermind. As mentioned in the video of Lee Robinson (at around minute 18) https://www.youtube.com/watch?v=8DyzsSWNcDE&ab_channel=LeeRobinson we lose nothing if we use a client component instead of a server component so it makes sense to make the form a client component. |
Beta Was this translation helpful? Give feedback.
-
![]() And if you use
|
Beta Was this translation helpful? Give feedback.
-
I created an issue on the react side since this seems to be an open point. |
Beta Was this translation helpful? Give feedback.
-
i get the solution
you can check the full code in my github link ![]() |
Beta Was this translation helpful? Give feedback.
-
Another way to reset the form is by using the prop key. I'm not entirely sure how recommended this approach is, but you can return a new state from the action and then use a key to reset the form. Here's a basic example: "use client";
import { useFormState } from "react-dom";
import { addPost } from "./actions";
export default function Home() {
const [state, action] = useFormState(addPost, { error: null });
return (
<main>
<form action={action} key={state?.resetKey}>
<input type="text" placeholder="Title" name="title" />
<button>Submit</button>
</form>
</main>
);
} "use server";
import { redirect } from "next/navigation";
export const addPost = (prevState, formData: FormData) => {
const title = formData.get("title")?.toString();
if (!title) {
return {
resetKey: prevState.resetKey,
error: "Title is required",
};
}
const post = createPost(title);
return {
error: null,
data: post,
resetKey: post.id,
};
};
function createPost(title: string) {
return {
id: Date.now(),
title,
};
} |
Beta Was this translation helpful? Give feedback.
-
Any new solution to this? I have a "use server" form and I can't clear my form. Seems like it should be something trivial right? |
Beta Was this translation helpful? Give feedback.
-
'use client'
import { useRef } from "react";
import { addTodo } from "../actions/addTodo";
function TodoForm() {
const ref = useRef<HTMLFormElement>(null);
return (
<form
ref={ref}
action={async (formData) => {
await addTodo(formData);
ref.current?.reset();
}}
>
<input
type="text"
placeholder="Enter your task here"
name="todo"
/>
<input name="isDone" type="checkbox" hidden />
<button>
<svg
width="24"
height="24"
viewBox="0 0 24 24"
stroke-width="2"
stroke="currentColor"
fill="none"
stroke-linecap="round"
stroke-linejoin="round"
type="submit"
>
<path stroke="none" d="M0 0h24v24H0z" />
<circle cx="12" cy="12" r="9" />
<line x1="9" y1="12" x2="15" y2="12" />
<line x1="12" y1="9" x2="12" y2="15" />
</svg>
<span>Add</span>
</button>
</form>
);
}
export default TodoForm; and action "use server";
import { revalidatePath } from "next/cache";
export async function addTodo(formData: FormData) {
const rawFormData = {
content: formData.get("todo"),
date: new Date().toISOString(),
isDone: formData.get("isDone") === "on" ? "true" : "false",
};
await fetch("http://localhost:8000/todos/add", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify(rawFormData),
});
formData.set("todo", " ");
revalidatePath("/");
} |
Beta Was this translation helpful? Give feedback.
-
I was running into this issue and using |
Beta Was this translation helpful? Give feedback.
-
This is my solution 'use client'
import { Input } from '@/components/ui/input'
import { Button } from '@/components/ui/button'
import { createMessage } from '@/lib/actions'
import { useState } from 'react'
export function NewMessageForm({
serverId,
channelId
}: {
serverId: string
channelId: string
}) {
const [content, setContent] = useState('')
return (
// add `onSubmit={() => setContent('')` to form element
<form action={createMessage} onSubmit={() => setContent('')}>
<div className="flex gap-2 p-2">
<input type="text" name="serverId" value={serverId} hidden readOnly />
<input type="text" name="channelId" value={channelId} hidden readOnly />
<Input
name="content"
value={content}
onChange={(e) => setContent(e.target.value)}
/>
<Button type="submit">Submit</Button>
</div>
</form>
)
} |
Beta Was this translation helpful? Give feedback.
-
In next.js 14.2 this is already fixed. |
Beta Was this translation helpful? Give feedback.
-
We have a custom Our component also handles the Form.tsximport { useEffect, useRef } from 'react';
export default function Form({
action,
children,
className,
state,
...rest
}: {
action: any;
children: React.ReactNode;
className?: string;
state: any;
rest?: React.HTMLProps<HTMLFormElement>;
}) {
const formRef = useRef<HTMLFormElement>(null);
useEffect(() => {
if (state.success) {
formRef?.current?.reset();
}
}, [state.success]);
return (
<form action={action} className={className} ref={formRef} {...rest}>
{children}
<p aria-live="polite" className="sr-only" role="status">
{state?.message}
</p>
</form>
);
} Example usage'use client';
import Form from '@/components/Form';
import { createBetaUser } from '@/app/auth/actions';
import { Field, Label } from '@/components/catalyst/fieldset';
import { initialFormState } from '@/lib/constants';
import { Input } from '@/components/catalyst/input';
import { useEffect } from 'react';
import { useFormState } from 'react-dom';
export default function BetaSignup() {
const [state, action] = useFormState(createBetaUser, initialFormState);
useEffect(() => {
if (state.success) {
// Do something that will only fire once on every unique success response.
}
}, [state.success]);
return (
<Form state={state} action={action}>
<Field>
<Label>Email</Label>
<Input
name="email"
placeholder="[email protected]"
required
type="email"
/>
</Field>
</Form>
);
} Server actionexport async function createBetaUser(
_prevState: {
status: string;
message?: string;
},
formData: FormData
) {
// ... do stuff.
return {
success: new Date().getTime(), // Providing a unique identifier here is important to allow the React component to respond to a changing `success` value.
message: 'good',
};
} |
Beta Was this translation helpful? Give feedback.
-
Client-side Code (/app/page.tsx)'use client';
import { useRef, useState } from 'react';
export default function Home() {
const inputRef = useRef(null);
const [status, setStatus] = useState('');
const handleSubmit = async (event) => {
event.preventDefault();
setStatus('Submitting...');
// Perform the server mutation here
try {
const response = await fetch('/api/submit', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({ input: inputRef.current.value }),
});
if (response.ok) {
inputRef.current.value = ''; // Reset the input field using ref
setStatus('Submission successful!');
} else {
setStatus('Submission failed.');
}
} catch (error) {
console.error('Failed to submit', error);
setStatus('Submission failed.');
}
};
return (
<div>
<form onSubmit={handleSubmit}>
<input
type="text"
ref={inputRef}
placeholder="Enter some text"
/>
<button type="submit">Submit</button>
</form>
<p>{status}</p>
</div>
);
} Server-side Code (/pages/api/submit.js)export default async function handler(req, res) {
if (req.method === 'POST') {
const { input } = req.body;
// Simulate a server mutation (e.g., save to database)
try {
// Example: Simulate a delay and successful response
await new Promise((resolve) => setTimeout(resolve, 1000));
// Respond with success
res.status(200).json({ message: 'Success', data: input });
} catch (error) {
console.error('Error during server mutation', error);
res.status(500).json({ message: 'Internal Server Error' });
}
} else {
res.setHeader('Allow', ['POST']);
res.status(405).end(`Method ${req.method} Not Allowed`);
}
} |
Beta Was this translation helpful? Give feedback.
-
Try this method const Page = () => {
const [resetKey, setResetKey] = useState(0);
const submit = async (formData) => {
await handleSubmit(formData);
setResetKey((prev) => prev + 1);
};
return (
<div>
<form key={resetKey} action={submit}>
<input name="myinput" type="text" />
</form>
</div>
);
}; |
Beta Was this translation helpful? Give feedback.
-
Summary
Hey,
How to clear / reset input after server mutation ?
I don't see any tutorial or so.
Please help.
Many Thanks!
Additional information
No response
Example
No response
Beta Was this translation helpful? Give feedback.
All reactions