Reputation: 67
I have a form with a html select tag that is populated with some data fetched and being passed as props to the form:
"use client";
const initialState: FormState<CreateSpecialtyFields> = {
errors: null,
message: null,
resultType: SnackbarTypes.INFO,
fieldsData: {
schoolId: 0,
},
};
const CreateSpecialtyForm = ({
schools,
}: {
schools: School[];
}) => {
const [state, formAction, isLoading] = useActionState(
createSpecialtyAction,
initialState,
);
return (
<form action={formAction}>
<select id="schoolId"
name="schoolId"
defaultValue={state.fieldsData.schoolId}
>
{schools.map((school) => (
<option key={school.id} value={school.id}>
{school.name}
</option>
))}
</select>
</form>
As in any field that makes use of useActionState, I need to return the previous values and use them to show the previous input to the user. The problem is that the select element is not keeping the previous value. I verified that the correct value is being returned, but it keeps keeping the first value on the list, even though the defaultValue is set. I don't see another way of working around this other than making the select tag a controlled input by storing the selection with a state hook. I rather keeping all my inputs uncontrolled unless it's strictly necessary. Any ideas or explanations on why this is happening?
Upvotes: 3
Views: 150
Reputation: 1
It is a bug that people are discussing, the only solution I can find is add a key
to the select
, as mentioned in this thread
Upvotes: 0
Reputation: 11
It seems to be a bug with React 19. I have a similar problem, and I also tried multiple solutions such as setting the defaultValue for the <select></select>
tag, or conditionally checking the selected value for the <option></option>
tag to no avail.
You might as well try a more "manual" solution, which is to manipulate the DOM after the form state updates:
function createSpecialtyAction(prevState, formData) {
//...your code
const selectedValue = formData.get("schoolId");
const selectEl = document.querySelector("select#schoolId");
setTimeout(() => {
if (selectEl) selectEl.value = selectValue;
}, 100);
return {...yourState};
}
This solution guarantees that you retain your state after submitting the form, but comes with the drawback of giving a bit of UI flickering.
Upvotes: 0
Reputation: 19
It seems to be a bug of React, there is an issue opened here. Unfortunately as of this writing the bug is still marked as Unconfirmed and there is no response from the React team.
Upvotes: 0