Пользовательский интерфейс материалов не может установить значение по умолчанию для автозаполнения

#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 -> > CodeSandbox

3. Я все изменил, и это работает безупречно. У меня просто был один вопрос, на который я не мог найти ответа даже в официальной документации. Что делать, если я не хотел получать объект взамен и вместо этого просто работал с идентификатором? Поэтому я передаю объекты в опции. Затем я использую getOptionLabel для установки атрибута метки (в моем случае имя). value возвращает объект и onChange также должен быть объектом. Что, если я хочу id , чтобы при изменении был установлен только атрибут, но при этом ярлык и прочее работали как обычно? Правка: понял, что это не имеет смысла. Спасибо за помощь!

4. Ваш комментарий не имеет смысла, но я бы проделал эту манипуляцию с обработчиком отправки и продолжал работать с объектами для вашего фактического компонента.

Ответ №2:

Вместо установки значения по умолчанию попробуйте установить состояние со значением по умолчанию, которое вы хотите, а затем установите value={thestate} , чтобы onChaange изменил то же состояние.

Комментарии:

1. Да, но тогда разве это не было бы вне формы крючка реакции? Я не хочу устанавливать его как отдельное состояние, а все остальные входы контролируются формой крючка.

2. Это простой способ, но да, вы правы, в этом случае проницательный ответ является лучшим.