#reactjs #autocomplete #material-ui #react-hook-form
Вопрос:
Я использую форму React Hook для установки значения gender
автозаполнения при загрузке данных из API. Но автозаполнение, похоже, не устанавливает данные. Мой основной компонент выглядит так:
// this function is used to set the default form values. for now, its just gender value
const setFormValues = () => {
setValue("gender", {id: 'male', name: 'Male'})
};
И в useEffect я запускаю вышеуказанную функцию всякий раз, когда данные загружаются.
// prerequisites consists of many objects. gender is one of them
useEffect(() => {
setFormValues();
}, [prerequisites]);
Вот как выглядит этот компонент:
<Controller
name={name}
control={control}
render={({field: {onChange}}) => (
<Autocomplete
onChange={(e, data) => onChange(data?.[onChangeAttribute])}
options={options || []}
getOptionLabel={(option) => option.name}
isOptionEqualToValue={(option, value) => option.id === value.id}
renderInput={(params) => <TextField {...params} placeholder="test" label="test"/>}
/>
)}
/>
Затем я перешел к документации, которая указала мне на это. В принципе, я могу передать значение по умолчанию. Затем я перешел к созданию состояния и настройке этого состояния с setFormValues()
помощью функции. Состояние устанавливалось правильно. Но когда я передаю его в defaultValue
, значение не устанавливается, а вместо этого показывает мне неконтролируемый компонент ошибки, используемый в качестве контролируемого компонента, и вместо этого использует его в качестве контролируемого компонента.
То, что я пытаюсь сделать:
Идея, которую я имел в виду, состояла в том, чтобы установить значение по умолчанию, которое поступает из вызова API при использовании эффекта. В принципе, страница-это страница «редактировать», и я хочу показать текущий выбор.
Ответ №1:
Вам не хватает, чтобы установить value
опору на <Autocomplete />
.
<Controller
name={name}
control={control}
render={({field: {onChange, value}}) => (
<Autocomplete
onChange={(e, data) => onChange(data?.[onChangeAttribute])}
options={options || []}
value={value}
getOptionLabel={(option) => option.name}
isOptionEqualToValue={(option, value) => option.id === value.id}
renderInput={(params) => <TextField {...params} placeholder="test" label="test"/>
}
/>
)}
/>
Также вы можете просто использовать RHF reset
, когда ваш вызов API должен возвращать другие значения формы.
useEffect(() => {
reset(prerequisites);
}, [prerequisites]);
Комментарии:
1. Поэтому, если значение пустое, оно возвращает
The 'getOptionLabel' method of Autocomplete returned undefined instead of a string for "".
2. Если значение
value
пустое, оно должно бытьnull
значением, чтобы<Autocomplete />
компонент мог проверить, что значение не указано. В противном случае он подумал бы, что""
это фактическое значение, а затем, конечно, не может связать его ни с одним из вашихoptions
. Проверьте этот рабочий пример того, как использовать a<Autocomplete />
с помощью RHF -> > CodeSandbox3. Я все изменил, и это работает безупречно. У меня просто был один вопрос, на который я не мог найти ответа даже в официальной документации. Что делать, если я не хотел получать объект взамен и вместо этого просто работал с идентификатором? Поэтому я передаю объекты в опции. Затем я использую
getOptionLabel
для установки атрибута метки (в моем случае имя).value
возвращает объект иonChange
также должен быть объектом. Что, если я хочуid
, чтобы при изменении был установлен только атрибут, но при этом ярлык и прочее работали как обычно? Правка: понял, что это не имеет смысла. Спасибо за помощь!4. Ваш комментарий не имеет смысла, но я бы проделал эту манипуляцию с обработчиком отправки и продолжал работать с объектами для вашего фактического компонента.
Ответ №2:
Вместо установки значения по умолчанию попробуйте установить состояние со значением по умолчанию, которое вы хотите, а затем установите value={thestate}
, чтобы onChaange изменил то же состояние.
Комментарии:
1. Да, но тогда разве это не было бы вне формы крючка реакции? Я не хочу устанавливать его как отдельное состояние, а все остальные входы контролируются формой крючка.
2. Это простой способ, но да, вы правы, в этом случае проницательный ответ является лучшим.