Skip to content

Commit 56d6220

Browse files
author
Erik Rasmussen
committed
Fix: Support type='select' for multiple select defaulting to []
- Previously only component='select' was checked for multiple select handling - Now also checks type='select' to match user expectations - Fixes react-final-form-arrays#185 where users pass type='select' multiple - Added 3 regression tests to verify fix - All tests pass (139/139, 99.32% coverage)
1 parent f1a4626 commit 56d6220

2 files changed

Lines changed: 79 additions & 2 deletions

File tree

src/useField.test.js

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -598,4 +598,81 @@ describe("useField", () => {
598598
expect(renderSpy.mock.calls[0][0]).toBe("Apple");
599599
expect(getByTestId("array").value).toBe("Apple");
600600
});
601+
602+
it("should default undefined value to [] for select multiple with type prop (fix react-final-form-arrays #185)", () => {
603+
const renderSpy = jest.fn();
604+
const MySelectField = () => {
605+
const { input } = useField("scopes", { type: "select", multiple: true });
606+
renderSpy(input.value);
607+
return (
608+
<select {...input} multiple data-testid="select">
609+
<option value="read">Read</option>
610+
<option value="write">Write</option>
611+
</select>
612+
);
613+
};
614+
render(
615+
<Form onSubmit={onSubmitMock}>
616+
{() => (
617+
<form>
618+
<MySelectField />
619+
</form>
620+
)}
621+
</Form>,
622+
);
623+
// When no initial value is provided, should default to [] not undefined
624+
// This prevents React warning: "The `value` prop supplied to <select> must be an array if `multiple` is true"
625+
expect(renderSpy.mock.calls[0][0]).toEqual([]);
626+
});
627+
628+
it("should default undefined value to [] for select multiple with component prop", () => {
629+
const renderSpy = jest.fn();
630+
const MySelectField = () => {
631+
const { input } = useField("scopes", { component: "select", multiple: true });
632+
renderSpy(input.value);
633+
return (
634+
<select {...input} multiple data-testid="select">
635+
<option value="read">Read</option>
636+
<option value="write">Write</option>
637+
</select>
638+
);
639+
};
640+
render(
641+
<Form onSubmit={onSubmitMock}>
642+
{() => (
643+
<form>
644+
<MySelectField />
645+
</form>
646+
)}
647+
</Form>,
648+
);
649+
// When no initial value is provided, should default to [] not undefined
650+
// This prevents React warning: "The `value` prop supplied to <select> must be an array if `multiple` is true"
651+
expect(renderSpy.mock.calls[0][0]).toEqual([]);
652+
});
653+
654+
it("should ensure select multiple value is always an array", () => {
655+
const renderSpy = jest.fn();
656+
const MySelectField = () => {
657+
const { input } = useField("scopes", { type: "select", multiple: true });
658+
renderSpy(input.value);
659+
return (
660+
<select {...input} multiple data-testid="select">
661+
<option value="read">Read</option>
662+
<option value="write">Write</option>
663+
</select>
664+
);
665+
};
666+
render(
667+
<Form onSubmit={onSubmitMock} initialValues={{ scopes: null }}>
668+
{() => (
669+
<form>
670+
<MySelectField />
671+
</form>
672+
)}
673+
</Form>,
674+
);
675+
// Even if the form value is null/undefined, input.value should be []
676+
expect(Array.isArray(renderSpy.mock.calls[0][0])).toBe(true);
677+
});
601678
});

src/useField.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,7 @@ function useField<
122122
// Use Form initialValues if available, otherwise use field initialValue
123123
let initialStateValue = formInitialValue !== undefined ? formInitialValue : initialValue;
124124

125-
if (component === "select" && multiple && initialStateValue === undefined) {
125+
if ((component === "select" || type === "select") && multiple && initialStateValue === undefined) {
126126
initialStateValue = [];
127127
}
128128

@@ -191,7 +191,7 @@ function useField<
191191
}
192192
}
193193

194-
if (component === "select" && multiple) {
194+
if ((component === "select" || type === "select") && multiple) {
195195
return Array.isArray(value) ? value : [];
196196
}
197197
// For checkboxes and radios, the `value` prop on the input element itself

0 commit comments

Comments
 (0)