Material UI - 使用 React Hook 表单自动完成

问题描述

我正在使用 Material UI 的自动完成功能构建一个表单,并使用反冲进行状态管理。我也在使用 react-hook-form。我需要满足以下条件:

  1. 需要预先输入,允许输入的第一个字母从 API 返回选项列表以显示自动完成中。每个字母都会返回不同的选项列表以供选择。
  2. 还需要允许 freeSolo,以便用户可以手动输入值
  3. 需要被要求并遵循某种模式来验证表单。

我使用 react-hook-form 的 <Controller> 来控制输入并允许验证、在帮助文本中显示错误消息等功能

问题:我在根据我输入的内容过滤选项以及允许 freeSolo 时遇到了问题。当我输入一个新值时,选项列表不会过滤。弹出窗口只是保持打开状态。我还需要验证模式验证的输入更改。我尝试使用以下带有 onInputChange 的示例来利用 react-hook-form 的 useFormsetValue 手动设置字段的值并验证表单。 ({shouldValidate: true})。下面的示例是我为 Autocomplete 创建的自定义、可重用组件,以及在其他父组件中使用该自定义组件。我希望我提供了尽可能多的细节,但如果没有,请让我知道您是否需要更多信息。任何帮助将不胜感激!

父组件:

  const setTrainType = useSetRecoilState(TrainType)
  // Trains would return a list of trains based on letter of train type that was passed from input
  const trainsList = useRecoilValue(Trains)
  const trainoptions = useMemo(() => trainsList.map(trainIDFormatted),[
    trainsList,])

const handleInputChange = useCallback(
    (_e: unkNown,option: string,reason: string) => {
      const capitalized =
        option === capitalize(option) ? option : capitalize(option)
      setValue('trainID',capitalized,{shouldValidate: true})
      if (['input','reset'].includes(reason) && capitalized !== '') {
        setTrainType(capitalized.charat(0))
      } else {
        setTrainType(undefined)
      }
    },[setTrainType,setValue],)

<Autocomplete
                autoSelect
                freeSolo
                disabled={disabled}
                helperText=" "
                label="Select a train"
                name="trainID"
                options={trainoptions}
                rules={{
                  pattern: {
                    message: 'Must match train ID pattern',value: /^(?:[A-Z]-?[A-Z ]{6}-?[0-9 ]-?[0-9 ]{2}[A-Z ])?$/,},required: 'Train is required',}}
                onInputChange={handleInputChange}
              />

自定义自动完成组件:

import {
  AutocompleteProps,Autocomplete as MuiAutocomplete,} from '@material-ui/lab'
import {get} from 'lodash'
import React,{ReactNode,useCallback} from 'react'
import {
  Controller,ControllerProps,FieldError,useFormContext,} from 'react-hook-form'
import {useRenderInput} from './hooks'

interface Props
  extends Pick<ControllerProps<'select'>,'rules'>,Omit<
      AutocompleteProps<string,false,true>,'error' | 'onChange' | 'required' | 'renderInput'
    > {
  helperText?: ReactNode
  label?: string
  name: string
}

/**
 * Render controlled autocomplete. Use react-form-hook's FormProvider.
 * @param props Component properties
 * @param props.helperText Default helper text for error
 * @param props.label Input label
 * @param props.name Name identifier for react-hook-form
 * @param props.required If true then item is required
 * @param props.rules Select rules
 * @return React component
 */
export const Autocomplete = ({
  helperText,label,name,rules,...props
}: Props) => {
  // eslint-disable-next-line @typescript-eslint/unbound-method
  const {control,errors,watch} = useFormContext()
  const error: FieldError | undefined = get(errors,name)
  const required = get(rules,'required') !== undefined
  const value = watch(name)
  const renderAutocompleteInput = useRenderInput({
    error: error !== undefined,helperText: get(error,'message',helperText),required,})
  const handleOnChange = useCallback(
    (_e: unkNown,option: string | null) => option,[],)
  const renderAutocomplete = useCallback(
    params => (
      <MuiAutocomplete
        {...props}
        {...params}
        renderInput={renderAutocompleteInput}
        onChange={handleOnChange}
      />
    ),[handleOnChange,props,renderAutocompleteInput],)

  return (
    <Controller
      control={control}
      defaultValue={value ?? ''}
      name={name}
      render={renderAutocomplete}
      rules={rules}
    />
  )
}

它的样子:

enter image description here

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...