Part 108: Enhancing User Experience in Next.js: Handling Server Action Responses in Client Component
[App] Server Actions

In modern web applications, delivering a seamless user experience is paramount. One way to achieve this is by effectively handling server responses and displaying relevant feedback to users. In this post, we'll explore how to manage server action responses in Next.js by transforming a CommentForm component into a Client Component. This allows us to provide immediate feedback to users based on server responses, such as error messages when form submissions fail.
Separating Server Logic for Client Components
To enable our CommentForm to function as a Client Component, we moved the server-side logic to a separate file. This separation allows us to handle server actions more flexibly and utilize client-side logic for better user interaction. Let's dive into the process of capturing server responses and displaying messages to users.
Handling Form Submissions Manually
Instead of directly binding the server action to the form element, we'll handle the onSubmit event manually. This approach gives us control over the form submission process and allows us to inspect server responses before displaying any messages to the user.
Implementing the handleSubmit Function
handleSubmit FunctionHere's how to implement the handleSubmit function to manage form submissions:
Prevent Default Form Submission: We begin by preventing the default browser action that would post the data directly to the server. This allows us to handle the form data manually.
Create FormData Instance: We create a new
FormDataobject, which is available globally in browsers. By passing the form element to theFormDataconstructor, we can automatically populate the object with form field values.Call the Server Action: We then call the server action
createCommentAction, passing theformDataas an argument. This call behaves like a regular function call, even though the action itself runs on the server.Log the Result: The result of the server action is logged to the console. If the server action returns an error, we can capture and display it to the user.
Here's how this looks in code:
// components/CommentForm.jsx
'use client';
import { createCommentAction } from '@/app/reviews/[slug]/actions';
export default function CommentForm({ slug, title }) {
const handleSubmit = async (event) => {
event.preventDefault();
const form = event.currentTarget;
const formData = new FormData(form);
const result = await createCommentAction(formData);
console.log('result:', result);
};
return (
<form onSubmit={handleSubmit}
className="border bg-white flex flex-col gap-2 mt-3 px-3 py-3 rounded">
<p className="pb-1">
Already played <strong>{title}</strong>? Have your say!
</p>
<input type="hidden" name="slug" value={slug} />
<div className="flex">
<label htmlFor="userField" className="shrink-0 w-32">
Your name
</label>
<input id="userField" name="user"
className="border px-2 py-1 rounded w-48"
/>
</div>
<div className="flex">
<label htmlFor="messageField" className="shrink-0 w-32">
Your comment
</label>
<textarea id="messageField" name="message"
className="border px-2 py-1 rounded w-full"
/>
</div>
<button type="submit"
className="bg-orange-800 rounded px-2 py-1 self-center
text-slate-50 w-32 hover:bg-orange-700">
Submit
</button>
</form>
);
}Testing and Validating
To test the setup, we initially log the formData to ensure it contains the expected values. Once verified, we proceed to call the server action and log the result. During testing, we temporarily remove client-side validation attributes to allow for empty form submissions, thereby triggering server-side validation errors.
When submitting an empty form, the server action returns an error object. This object contains a message like "Name field is required," which we can use to provide user feedback.
Understanding Network Requests
Next.js handles the server action call by making a fetch request to the server, submitting the form data via a POST request. The response from the server includes the serialized JSON object that the server action returns, allowing us to process server feedback on the client side.
Conclusion
By handling server action responses in client-side code, we can provide immediate and informative feedback to users, enhancing their experience. This approach demonstrates the power of Next.js Server Actions, which function as a form of Remote Procedure Call (RPC) integrated seamlessly into the framework.
In future posts, we'll explore how to display server error messages to users and manage successful form submissions, ensuring a robust and user-friendly application. Stay tuned for more insights into building effective web applications with Next.js!
Last updated