fix: Improve option filtering in V2Select component
- Updated the option filtering logic to handle null and undefined values, preventing potential crashes when cmdk encounters these values. - Introduced a safeOptions variable to ensure that only valid options are processed in the dropdown and command list. - Enhanced the setOptions function to sanitize fetched options, ensuring that only valid values are set, improving overall stability and user experience.
This commit is contained in:
parent
0f52c3adc2
commit
c1f7f27005
|
|
@ -80,7 +80,7 @@ const DropdownSelect = forwardRef<HTMLButtonElement, {
|
||||||
</SelectTrigger>
|
</SelectTrigger>
|
||||||
<SelectContent>
|
<SelectContent>
|
||||||
{options
|
{options
|
||||||
.filter((option) => option.value !== "")
|
.filter((option) => option.value != null && option.value !== "")
|
||||||
.map((option) => (
|
.map((option) => (
|
||||||
<SelectItem key={option.value} value={option.value}>
|
<SelectItem key={option.value} value={option.value}>
|
||||||
{option.label}
|
{option.label}
|
||||||
|
|
@ -112,6 +112,12 @@ const DropdownSelect = forwardRef<HTMLButtonElement, {
|
||||||
}
|
}
|
||||||
|
|
||||||
// 검색 가능 또는 다중 선택 → Combobox 사용
|
// 검색 가능 또는 다중 선택 → Combobox 사용
|
||||||
|
// null/undefined value를 가진 옵션 필터링 (cmdk가 value={null}일 때 크래시 발생)
|
||||||
|
const safeOptions = useMemo(() =>
|
||||||
|
options.filter((o) => o.value != null && o.value !== ""),
|
||||||
|
[options]
|
||||||
|
);
|
||||||
|
|
||||||
const selectedValues = useMemo(() => {
|
const selectedValues = useMemo(() => {
|
||||||
if (!value) return [];
|
if (!value) return [];
|
||||||
return Array.isArray(value) ? value : [value];
|
return Array.isArray(value) ? value : [value];
|
||||||
|
|
@ -119,9 +125,9 @@ const DropdownSelect = forwardRef<HTMLButtonElement, {
|
||||||
|
|
||||||
const selectedLabels = useMemo(() => {
|
const selectedLabels = useMemo(() => {
|
||||||
return selectedValues
|
return selectedValues
|
||||||
.map((v) => options.find((o) => o.value === v)?.label)
|
.map((v) => safeOptions.find((o) => o.value === v)?.label)
|
||||||
.filter(Boolean) as string[];
|
.filter(Boolean) as string[];
|
||||||
}, [selectedValues, options]);
|
}, [selectedValues, safeOptions]);
|
||||||
|
|
||||||
const handleSelect = useCallback((selectedValue: string) => {
|
const handleSelect = useCallback((selectedValue: string) => {
|
||||||
if (multiple) {
|
if (multiple) {
|
||||||
|
|
@ -191,7 +197,7 @@ const DropdownSelect = forwardRef<HTMLButtonElement, {
|
||||||
<Command
|
<Command
|
||||||
filter={(itemValue, search) => {
|
filter={(itemValue, search) => {
|
||||||
if (!search) return 1;
|
if (!search) return 1;
|
||||||
const option = options.find((o) => o.value === itemValue);
|
const option = safeOptions.find((o) => o.value === itemValue);
|
||||||
const label = (option?.label || option?.value || "").toLowerCase();
|
const label = (option?.label || option?.value || "").toLowerCase();
|
||||||
if (label.includes(search.toLowerCase())) return 1;
|
if (label.includes(search.toLowerCase())) return 1;
|
||||||
return 0;
|
return 0;
|
||||||
|
|
@ -201,7 +207,7 @@ const DropdownSelect = forwardRef<HTMLButtonElement, {
|
||||||
<CommandList>
|
<CommandList>
|
||||||
<CommandEmpty>검색 결과가 없습니다.</CommandEmpty>
|
<CommandEmpty>검색 결과가 없습니다.</CommandEmpty>
|
||||||
<CommandGroup>
|
<CommandGroup>
|
||||||
{options.map((option) => {
|
{safeOptions.map((option) => {
|
||||||
const displayLabel = option.label || option.value || "(빈 값)";
|
const displayLabel = option.label || option.value || "(빈 값)";
|
||||||
return (
|
return (
|
||||||
<CommandItem
|
<CommandItem
|
||||||
|
|
@ -869,7 +875,11 @@ export const V2Select = forwardRef<HTMLDivElement, V2SelectProps>(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
setOptions(fetchedOptions);
|
// null/undefined value 필터링 (cmdk 크래시 방지)
|
||||||
|
const sanitized = fetchedOptions.filter(
|
||||||
|
(o) => o.value != null && String(o.value) !== ""
|
||||||
|
).map((o) => ({ ...o, value: String(o.value), label: o.label || String(o.value) }));
|
||||||
|
setOptions(sanitized);
|
||||||
setOptionsLoaded(true);
|
setOptionsLoaded(true);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("옵션 로딩 실패:", error);
|
console.error("옵션 로딩 실패:", error);
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue