Next.js Discord

Discord Forum

Multiple calls to modify a single state object with useActionState?

Unanswered
African Slender-snouted Crocodil… posted this in #help-forum
Open in Discord
Avatar
African Slender-snouted CrocodileOP
I'm trying to build a form in which the bulk of the form is held in a Component which uses useActionState and the (main) action function processes all of the form data.
Within the form, I have a field/array of fields (open to changing the mechanism...) which can be dynamically created/deleted by the user. As a pseudo-example:

const [state, formAction] = useActionState(submitFormAction, { myEmail: '', friendEmails: [] });

return (
<form action={formAction}>
// Consider this to have appropriate label in a div or whatever, along with a bunch more props
<input id='myEmail' />

// Dynamic elements
{state.friendEmails.map((email, idx) => {
  return (
    <>
      <input id={`friendEmails.${idx}`} defaultValue={state.friendEmails[idx]} />
      // Need another action here... Probably also need to bind the index to delete
      <button formAction={deleteFriendAction}>X</button>
    </>
})}
// Add more friends... a third action
<button formAction={addNewFriend}>Add a Friend</button>

<button type='submit'>Submit</button>
</form>
)


I can consider binding an action ('add' | 'remove' | 'submit') to the formAction, but I'm unsure if that will help me...
I want to ensure that the state object contains the appropriate number of friendEmails, and that they each retain their values when I add/remove a friend (well, except the one I delete of course...), but I'd like to use useActionState to provide progressive enhancement (doing this on the client side is not so hard, I guess, but working out a suitable way to get it done via form action has me stumped).

I then figure I can useOptimistic and onClick handlers with ev.preventDefault() to prevent the form action, and call the add/remove form action functions inside the handler, to provide responsive client-side behaviour without the delay of a server round-trip...

Is this doable? How can I best achieve this?

0 Replies