Reactjs 物料界面-使用反应挂钩表单自动完成
我正在使用MaterialUI的自动完成功能构建表单,并使用反冲进行状态管理。我还使用了react-hook形式。我需要满足以下标准:Reactjs 物料界面-使用反应挂钩表单自动完成,reactjs,material-ui,react-hook-form,recoiljs,Reactjs,Material Ui,React Hook Form,Recoiljs,我正在使用MaterialUI的自动完成功能构建表单,并使用反冲进行状态管理。我还使用了react-hook形式。我需要满足以下标准: 需要typeahead,它允许键入的第一个字母返回API中显示在自动完成中的选项列表。每个字母将返回一个不同的选项列表以供选择 还需要允许freeSolo,以便用户可以手动输入值 需要是必需的,并遵循一种模式来验证表单 我使用react hook表单的来控制输入,并允许验证、在帮助器文本中显示错误消息等功能 问题:我对基于我键入的内容筛选出的typeahead选
来控制输入,并允许验证、在帮助器文本中显示错误消息等功能
问题:我对基于我键入的内容筛选出的typeahead选项以及允许freeSolo存在问题。键入新值时,选项列表不会过滤。弹出窗口保持打开状态。我还需要对模式验证输入的更改进行验证。我尝试了以下示例,使用onInputChange
使用react钩子表单的useForm
和setValue
手动设置字段值并验证表单。({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}
/>
const setTrainType=UseSetRecocilState(列车类型)
//Trains将根据输入传递的列车类型字母返回列车列表
const trainsList=useRecoilValue(列车)
const trainOptions=useMoom(()=>trainsList.map(trainIDFormatted)[
列车名单,
])
const handleInputChange=useCallback(
(_e:unknown,option:string,reason:string)=>{
常数资本化=
选项===资本化(选项)?选项:资本化(选项)
setValue('trainID',大写,{shouldValidate:true})
如果(['input','reset'])。包括(原因)&大写!=''){
setTrainType(大写字符(0))
}否则{
setTrainType(未定义)
}
},
[setTrainType,setValue],
)
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, 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),
label,
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}
/>
)
}