你能告诉我为什么我收到错误“组件正在将不受控制的自动完成更改为受控制。 元素不应从不受控制切换到受控制(反之亦然)。 决定在组件的生命周期内使用受控或不受控的自动完成元素。”
成分:
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}
/>
);
}
调用自动完成:
<Controller
control={control}
name = 'country'
as = {
<AutoComplete
options={countryOptions}
onChange={selectCountryHandler}
label="Country"
value={selectedCountry || ''}
/>
} />
如何解决这个错误?
您确保 value 属性从未未定义,但您必须对 inputValue 执行相同操作。
当⚠️这两个状态是隔离的,应该独立控制。
inputValue 属性未定义时,组件将变得不受控制,反之亦然。
如果在下面的示例中您删除了一个空字符串
React.useState('')
您将收到相同的错误消息,因为第一次渲染期间的inputValue是undefined
。
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>
)
}
未选择任何值时,需要添加
|| null
以防止自动完成进入不受控制模式:
<Autocomplete {...props} value={props.value || null} />
如果将
value={undefined}
传递给自动完成组件,它将以“不受控制”模式启动,这意味着它保持自己的内部状态。然后,如果您稍后提供 value
,则会引发“A 组件正在更改”错误。但是,如果您传递 value={null}
而不是 value={undefined}
,则会导致自动完成以受控模式启动。自动完成将假设您将提供状态,而不是保留其自己的状态,并且错误会消失。
我通过删除
default value
解决了这个问题。
<Autocomplete
multiple
id="multiple-limit-tags"
options={(option) => option.label}
getOptionLabel={(option) => option}
// defaultValue={options || []}
renderInput={(params) => <TextField {...params} label="My Label" />}
/>
如何解决这个问题并不明显,而且文档也没有多大帮助。我觉得奇怪的是,文档中的复制粘贴示例会导致此错误。我想这个例子是有效的,因为选择是硬编码的。
我今天遇到了同样的问题,但我能够通过提供默认值 null 以及在它不存在的情况下提供 null 值来解决它。我将留下对我有用的代码:
<Autocomplete
value={filters.tag || null}
defaultValue={null}
options={tags || []}
getOptionLabel={(option) => option}
renderInput={(params) => (
<TextField {...params} label="Search" variant='outlined' size='small' />
)}
fullWidth
onChange={(event, value) => {
if (value) {
setFilters({ ...filters, tag: value });
} else {
setFilters({ ...filters, tag: '' });
}
}}
/>
之前的答案绝对正确,但是我花了 20 分钟才弄清楚 inputValue 应该是 value 我的工作示例:
export default function AddModal(): ReactElement {
const [resource, setResource] = useState('one');
<Autocomplete
id="autocomplete"
options={['one', 'two']}
defaultValue={resource}
value={resource}
PopperComponent={StyledPopper}
onChange={(event, newInputValue) => setResource(newInputValue)}
renderInput={(params) => <TextField {...params} />}
/>
对我来说,我通过更新
onChange
函数并添加 || null
解决了这个问题,而不是删除默认值,因为我仍然需要它,这里是代码
<Box mt={2}>
<Controller
control={control}
name="thematic"
rules={{
required: 'Veuillez choisir une réponse',
}}
render={({ field: { onChange } }) => (
<Autocomplete
defaultValue={
questionData?.thematic ? questionData?.thematic : null
}
options={thematics}
getOptionLabel={(option) => option.name}
onChange={(event, values) => {
onChange(values || null)
}}
renderInput={(params) => (
<TextField
{...params}
label="Thématique"
placeholder="Thématique"
helperText={errors.thematic?.message}
error={!!errors.thematic}
/>
)}
/>
)}
/>
</Box>
对于带有选项的自动完成功能,这是一个没有对象的简单数组,您可以简单地这样做,并且您想得到任何问题
<Box mt={2}>
<Controller
control={control}
name="type"
rules={{
required: 'Veuillez choisir une réponse',
}}
render={({ field: { onChange, value } }) => (
<Autocomplete
freeSolo
options={['Champ', 'Sélection', 'Choix multiple']}
onChange={(event, values) => onChange(values)}
value={value}
renderInput={(params) => (
<TextField
{...params}
label="Type de la question"
variant="outlined"
onChange={onChange}
helperText={errors.type?.message}
error={!!errors.type}
/>
)}
/>
)}
/>
</Box>
如果您使用react-hook-form,您可以在
useForm
内设置默认值
const {
handleSubmit,
control,
watch,
register,
formState: { errors },
} = useForm({
defaultValues: {
...
type: questionData?.type ? mapperQuestionType[questionData?.type] : '',
},
})
对我来说,问题是我的组件返回一个
<Autocomplete>
组件,如果它处于加载状态,与加载状态相比,它具有不同的 props 集。前一组道具表示不受控制的 <Autocomplete>
,而后者表示受控制的:
import {Autocomplete, TextField} from '@mui/material';
import React, {useState} from 'react';
export type MyComponentProps =
| {
loading: true;
}
| {
loading: false;
options: string[];
value: string;
setValue: (value: string) => void;
};
export const MyComponent = (props: MyComponentProps) => {
const [inputValue, setInputValue] = useState('');
if (props.loading) {
return (
<Autocomplete
loading
disabled
id="my-component"
options={[]}
renderInput={(params) => <TextField {...params} label="My Component" />}
// Adding these two props fixed the error message:
// value={null}
// inputValue=""
/>
);
}
return (
<Autocomplete
value={props.value}
onChange={(_, newValue) => {
props.setValue(newValue ?? '');
}}
id="my-component"
options={props.options}
inputValue={inputValue}
onInputChange={(_, newInputValue) => {
setInputValue(newInputValue);
}}
renderInput={(params) => <TextField {...params} label="My Component" />}
/>
);
};