reactjsforms

How to handle dropdowns in forms with useActionState in React 19+


I'm in the process of building a form using the inbuilt form handler from React version 19, with the inbuilt useActionState hook.

When binding the input values with the form for say a standard text input, I have the equivalent of below, where anything input will amend the firstName field of my form. This is also handled so that if a record is loaded from the api, the firstName input is populated by default.

          <InputText
            name="firstName"
            className={`formState.errors?.firstName && 'error border-1 border-red-500'}`}
            defaultValue={formState.enteredValues?.firstName}
            required
          />

What I can't find the documentation for is how to bind the values for a Dropdown component as cleanly. Is there a way to bind the value directly, without having to use some extra state? I was hoping for something like below

          <Dropdown
            name='gender'
            options={['male', 'female', 'other']}
            className={`${!isPending && formState.errors?.gender && 'error border-1 border-red-500'}`}
            defaultValue={formState.enteredValues?.gender}
          />

And then changing the value of the dropdown will directly append the 'gender' value to the form. Rather than having to use a bit of state in the middle, which is amended onChange.

Any advice is appreciated. Thanks


Solution

  • Actually i don't quite understand what problem is. I think reproducable example from you would fix that.

    But anyway, i "feel" that you have some difficulties with React 19 forms. I felt the same way a few months ago when i was trying to use them

    Basically, what i see. You need to keep in mind a few points

    1. name='gender' ensures the selected option is included in the FormData

    2. defaultValue sets the initial selected option. This is required for uncontrolled components

    3. formData.get('gender') works exactly like with text inputs

    4. This works out of the box in React 19 server actions

    5. If you’re using a controlled component (value, onChange), it won’t submit the value unless it's also reflected in the form state — better stick to uncontrolled for server actions

    Here is a live example for you in codesandbox and it's listing below

    import React from "react";
    
    async function handleSubmit(prevState: any, formData: FormData) {
      "use server";
      const gender = formData.get("gender");
    
      console.log("Selected gender:", gender);
    
      return { success: true, gender };
    }
    
    export default function SosijElizabethForm() {
      const [state, formAction] = React.useActionState(handleSubmit, {});
    
      console.log("Form state:", state);
    
      return (
        <form action={formAction}>
          <label>
            Choose gender:
            <select name="gender" defaultValue="Male">
              <option value="male">Male</option>
              <option value="female">Female</option>
              <option value="other">Other</option>
            </select>
          </label>
    
          <button type="submit">Submit</button>
    
          {state.gender && <p>Selected gender: {state.gender}</p>}
        </form>
      );
    }
    

    Furthermote. Personally i didn't like React 19 form. I didn't find them flexible as react-hook-form. Hope in the future they would be more ... React'ish

    I don't like that