MUI 的 Autocomplete AS MULTIPLE input + react-hook-form + 控制默认值不起作用(TypeError: Can't read property 'filter' of undefined)

IT技术 reactjs autocomplete material-ui react-hook-form
2021-05-25 15:09:21

我想使用Material-UI Autocomplete与多个输入react-hook-formcontroldefaultValues自动完成的动态(下呈现组件预填充,编辑数据的基础上,已保存的数据时,从数据库中读取)。

所以主要问题是:

控制Material-UI Autocomplete组件中的默认值并将其与 一起使用的最佳方法是什么react-hook-form

到目前为止我做了什么:

  1. 通过在 React 中使用函数和钩子,我在 React 钩子表单中包装了一个自动完成组件Controller来控制状态。我试图从 MUI 的文档和react-hook-form以下线程的解决方案中实现解决方案。

    我在这里创建了一个最小的沙箱

它能做什么

当我设置defaultValuein 时Controller,它可以显示受控的默认值,但会引发错误:TypeError: Cannot read property 'filter' of undefined

  <Controller
      as={
      <Autocomplete
        multiple
        value={defaultValues}
        onChange={(e, values) => setValue("food", values)}
        ...
        renderInput={params => ( ... )}
      />
    }
    control={control}
    name="food"
    defaultValue={defaultValues} // <- this makes the error
  />

当我不设置defaultValuein 时Controller,它可以完美地选择multiple预期的值,但它不显示默认值。

令人困惑的是,Autocomplete必须控制value/onChange并且Controller必须控制defaultValue/setValue,在我的情况下它们似乎冲突。

  1. 设置defaultValue={ [] }和使用 a useEffect并仅使用控制默认值 时效果更好setValue("food", defaultOption);

    所以我在这里创建了另一个沙箱

  2. 感谢比尔的回答,我将代码重构为文档中提出的 renderProp :

    这里还有一个沙箱

    现在它就像一个魅力,但我不得不设置这样的onChangepropsAutocomplete

    onChange={(e, values) => setValue("food", values)}

    而不是文档建议做的:(使用传递的 onChange)

    onChange={e => props.onChange(e.something)}

    它有效,但这是组合Autocompleteand 的正确方法react-hook-form吗?

将问题与这些线程进行比较:

与我尝试做的其他线程的主要区别是设置defaultValuesa 的multiple Autocomplete.

使用带有 Material-UI 自动完成功能的 react-hook-form Controller 的正确方法

与 react-hook-form 的控制器一起使用时,MUI 自动完成的“defaultValue”不起作用

为什么未使用 react-hook-form 在 Material UI Autocomplete 中设置初始值?

文档中的建议解决方案react-hook-form

https://react-hook-form.com/api/#Controller

以及来自Material UI文档的代码

https://material-ui.com/components/autocomplete/#multiple-values

3个回答

通过执行以下操作,我能够使其正常工作:

                                <Controller
                                    name='test'
                                    control={control}
                                    render={({onChange, ...props}) => (
                                        <AutoComplete
                                            {...props}
                                            data-testid='test-select'
                                            width={350}
                                            label='Auto Complete'
                                            onChange={onChange}
                                            options={eventTypes}
                                            getOptionLabel={(option) => option ? option.name : ''}
                                            renderOption={(option) => option.name }
                                            getOptionSelected={(option) => option.name}
                                            renderInput={(params) => (
                                                <TextField {...params} error={error} helperText={helperText} label={label} placeholder={label} />
                                            )}
                                            onChange={(e, data) => onChange(data)}
                                            {...props}
                                        />
                                    )}
                                />

但是,我还没有找到使用 react-hook-form 来验证这一点的方法

您可以尝试自定义验证(如果您使用 MUI 的自动完成功能 with multiple={true}):

<Controller
...
rules={{
   validate: (data) => {
     if(data.length === 0) return false;
   }
}}
/>

现在它就像一个魅力,但我必须像这样设置自动完成的 onChange props:

onChange={(e, values) => setValue("food", values)}

你可以做 onChange={(e, newValue) => props.onChange(newValue)}