组件正在将不受控制的自动完成更改为受控

kin*_*nza 23 controller autocomplete reactjs material-ui react-hook-form

你能告诉我为什么我收到错误“一个组件正在改变一个不受控制的自动完成来控制。元素不应该从不受控制切换到受控制(反之亦然)。决定在整个生命周期内使用受控制或不受控制的自动完成元素组件。”

成分 :


function AutoComplete(props) {

  const defaultProps = {
    options: props.options,
    getOptionLabel: option => option.name,
  };

  const handleChange = (e, value) => {
    props.onChange(value);
  };

  return (
    <Autocomplete
      {...defaultProps}
      renderInput={params => (
        <TextField {...params} label={props.label} margin="normal" />
      )}
      onChange={handleChange}
      value={props.value}
    />
  );
}

Run Code Online (Sandbox Code Playgroud)

调用自动完成:

               <Controller
                control={control}
                name = 'country'
                as = {
                  <AutoComplete
                    options={countryOptions}
                    onChange={selectCountryHandler}
                    label="Country"
                    value={selectedCountry  || ''}
                  />
                } />
Run Code Online (Sandbox Code Playgroud)

我该如何解决这个错误?

小智 41

当未选择任何值时,您需要添加|| null以防止自动完成进入不受控制模式:

<Autocomplete {...props} value={props.value || null} />
Run Code Online (Sandbox Code Playgroud)

如果您传递value={undefined}给自动完成组件,它将以“不受控制”模式启动,这意味着它保持自己的内部状态。然后,如果您稍后提供 a ,value则会引发“A 组件正在更改”错误。但是,如果您通过value={null}而不是通过value={undefined},则会导致自动完成以受控模式启动。自动完成将假定您将提供状态,而不是保留其自己的状态,并且错误会消失。


Spa*_*atz 15

您确保value属性从未未定义,但您必须对inputValue执行相同的操作

  1. 带有 value/onChange 道具组合的“value”状态。此状态表示用户选择的值,例如按 Enter 时。
  2. 带有 inputValue/onInputChange 道具组合的“输入值”状态。此状态表示文本框中显示的值。

?? 这两种状态是隔离的,应该独立控制。

inputValue属性未定义时,组件变得不受控制,反之亦然。

如果在下面的示例中删除一个空字符串, React.useState('')您将收到相同的错误消息,因为第一次渲染期间的inputValueundefined.

import React from 'react'
import TextField from '@material-ui/core/TextField'
import Autocomplete from '@material-ui/lab/Autocomplete'

const options = ['Option 1', 'Option 2']

export default function AutocompleteLab() {
  const [value, setValue] = React.useState(options[0])
  const [inputValue, setInputValue] = React.useState('')

  return (
    <div>
      <div>{`value: ${value !== null ? `'${value}'` : 'null'}`}</div>
      <div>{`inputValue: '${inputValue}'`}</div>
      <br />
      <Autocomplete
        value={value}
        onChange={(_, newValue) => {
          setValue(newValue)
        }}
        inputValue={inputValue}
        onInputChange={(_, newInputValue) => {
          setInputValue(newInputValue)
        }}
        options={options}
        style={{ width: 300 }}
        renderInput={(params) => <TextField {...params} label="Name" variant="outlined" />}
      />
    </div>
  )
}

Run Code Online (Sandbox Code Playgroud)


Ema*_*röm 6

我通过删除default value.

             <Autocomplete
                multiple
                id="multiple-limit-tags"
                options={(option) => option.label}
                getOptionLabel={(option) => option}
                // defaultValue={options || []}
                renderInput={(params) => <TextField {...params} label="My Label" />}           
              />
Run Code Online (Sandbox Code Playgroud)

如何解决这个问题并不明显,而且文档也没有多大帮助。我觉得奇怪的是,文档中的复制粘贴示例会导致此错误。我想这个例子是有效的,因为选择是硬编码的。