如何在react-hook-form中正确实现可创建的Mantine MultiSelect?
问题描述
我尝试在react-hook-form受控表单中集成可创建新选项的Mantine MultiSelect,但在正确实现onCreate属性时遇到困难。
组件代码
import type { SelectItem } from '@mantine/core' import { MultiSelect } from '@mantine/core' import { Controller, useFormContext } from 'react-hook-form' export default function ManMultiSelect({ name = '', label = '', data = [''], placeholder = '', disabled = false, searchable = false, nothingFound = 'Leider nichts gefunden', creatable = false, }) { const { control } = useFormContext() return ( <Controller name={name} control={control} render={({ field: { value, onChange } }) => ( <MultiSelect placeholder={placeholder} label={label} value={value as string[]} onChange={onChange} data={data as (string | SelectItem)[]} disabled={disabled} clearable creatable={creatable} getCreateLabel={(query) => `+ Füge ${query} hinzu`} // onCreate={} searchable={searchable} nothingFound={nothingFound} className="w-full" /> )} /> ) }
组件调用代码
<ManMultiSelect name="trainings" label="Fortbildungen der Einrichtung" creatable={true} searchable={true} placeholder="Hier die erfolgreich absolvierten Fortbildungen eintragen" data={facilityDetails?.trainings || []} />
请问如何正确使用value、onChange或实现onCreate来创建新值?
解决方案
要实现创建新选项并同步到react-hook-form的表单值,需要处理onCreate回调,同时确保新创建的选项被正确添加到表单选中值中。如果希望新选项后续能在下拉列表中被选择,还需更新数据源data。
1. 基础实现:创建新选项并同步表单值
修改ManMultiSelect组件,实现onCreate方法:
import type { SelectItem } from '@mantine/core' import { MultiSelect } from '@mantine/core' import { Controller, useFormContext } from 'react-hook-form' // 添加可选回调,用于通知父组件更新数据源 type Props = { name?: string; label?: string; data?: (string | SelectItem)[]; placeholder?: string; disabled?: boolean; searchable?: boolean; nothingFound?: string; creatable?: boolean; onAddNewOption?: (value: string) => void; } export default function ManMultiSelect({ name = '', label = '', data = [''], placeholder = '', disabled = false, searchable = false, nothingFound = 'Leider nichts gefunden', creatable = false, onAddNewOption, }: Props) { const { control } = useFormContext() return ( <Controller name={name} control={control} render={({ field: { value, onChange } }) => { const handleCreate = (newValue: string) => { // 避免重复添加到表单选中值 if (!value?.includes(newValue)) { onChange([...(value || []), newValue]) } // 通知父组件更新数据源(可选) onAddNewOption?.(newValue) } return ( <MultiSelect placeholder={placeholder} label={label} value={value as string[]} onChange={onChange} data={data as (string | SelectItem)[]} disabled={disabled} clearable creatable={creatable} getCreateLabel={(query) => `+ Füge ${query} hinzu`} onCreate={creatable ? handleCreate : undefined} searchable={searchable} nothingFound={nothingFound} className="w-full" /> ) }} /> ) }
2. 父组件更新数据源(可选)
如果希望新创建的选项能持久显示在下拉列表中,需要在父组件中维护data的状态,并通过onAddNewOption回调更新:
import { useState } from 'react' import ManMultiSelect from './ManMultiSelect' const ParentComponent = () => { const [trainings, setTrainings] = useState(facilityDetails?.trainings || []) const handleAddNewTraining = (newTraining: string) => { // 避免重复添加到数据源 if (!trainings.includes(newTraining)) { setTrainings([...trainings, newTraining]) } } return ( <ManMultiSelect name="trainings" label="Fortbildungen der Einrichtung" creatable={true} searchable={true} placeholder="Hier die erfolgreich absolvierten Fortbildungen eintragen" data={trainings} onAddNewOption={handleAddNewTraining} /> ) }
关键点说明
onCreate会接收用户输入的新选项值,通过onChange将其添加到react-hook-form的选中数组中,完成表单值更新。- 若要让新选项出现在下拉列表,必须更新
data属性——由于子组件不能直接修改props,需由父组件维护数据源状态并接收回调更新。 - 加入重复值判断,避免表单值或数据源出现重复项。
内容的提问来源于stack exchange,提问作者Giuseppe Bosco
相关产品推荐
相关产品推荐

