You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.29 07:42:46