Next.js Discord

Discord Forum

UI Update when using server action

Answered
New Guinea Freshwater Crocodile posted this in #help-forum
Open in Discord
Avatar
New Guinea Freshwater CrocodileOP
I'm trying out RSC and want to trigger an overlay that says "Message Sent" when the form is sent.

I'm reading the docs but I'm a bit confused.

This is what I have so far and it works the email gets sent but not sure how to trigger an UI update.
I don't want to trigger a redirect since this is a static website with one page
import { FormInput } from './Input'

export default function Form() {
  async function sendMessage(data) {
    'use server'

    const formDataObj = {}
    for (let [name, value] of data.entries()) {
      if (name === 'name' || name === 'email' || name === 'message') {
        formDataObj[name] = value
      }
    }

    return await sendSESMail(formDataObj)
  }

  return (
    <form action={sendMessage} className='flex flex-col gap-4 z-2'>
      <FormInput
        label='Your Name'
        type='text'
        name='name'
        placeholder='John Doe'
        required={true}
      />
      <FormInput
        label='Your Email'
        type='email'
        name='email'
        placeholder='john.doe@email.com'
        required={true}
      />
      <label htmlFor='message' className='flex flex-col gap-2'>
        <span className='text-brand-white'>Your Message</span>
        <textarea
          name='message'
          className='p-2 bg-brand-white'
          placeholder='Your message here...'
          rows={5}
          required={true}
        />
      </label>

      <button className='bg-brand-gold p-2 mt-4' type='submit'>
        Send Message
      </button>
    </form>
  )
}
Answered by New Guinea Freshwater Crocodile
The solution was to move the server action outside the component and make the component a client component.
View full answer

9 Replies

Avatar
Polar bear
You will need to use a client componet ("use client") and add handler for form actions that calls your server action
async function handleSendMessage(formData: FormData) {
  try {
    const data = await sendMessage(formData);
    console.log(data);
    // let use know message was sent
  } catch (error) {
    console.log(error);
  }
}

And change form action to handleSendMessage
Avatar
New Guinea Freshwater CrocodileOP
Is this a missing feature?
Avatar
nope
you want to do a client action from a server action
its not a missing feature, its misplaced expectation
Avatar
New Guinea Freshwater CrocodileOP
So it needs to be a client component but the action can still use useServer?
Avatar
you can either make it a client component, or think outside the box with all the other ways you can do it... like with a header... or a cookie... etc
Avatar
New Guinea Freshwater CrocodileOP
Cool thanks
Avatar
New Guinea Freshwater CrocodileOP
The solution was to move the server action outside the component and make the component a client component.
Answer