DefaultValues ​​формы response-hook-form не устанавливает значения для полей ввода в React JS

Я хочу указать значения по умолчанию в поле ввода, используя react-hook-form. Сначала я получаю пользовательские данные из конечной точки API, а затем устанавливаю состояние users для этих пользовательских данных. Затем я передаю состояние users в defaultValues из useForm().

import React, { useState, useEffect } from "react";
import { useForm } from "react-hook-form";
import axios from "axios";

function LoginFile() {
  const [users, setUsers] = useState(null);

  useEffect(() => {
    axios
      .get("http://localhost:4000/users/1")
      .then((res) => setUsers(res.data));
  }, []);

  useEffect(() => {
    console.log(users);
  }, [users]);

  const { register, handleSubmit, errors } = useForm({
    defaultValues: users,
  });
 return (
    <div>
      <form onSubmit={handleSubmit(onSubmit)}>
        Email <input type="email" name="email" ref={register} /><br />
        firstname <input name="firstname" ref={register} /><br/>
        <input type="submit" />
      </form>
    </div>
 );
}
export default LoginFile;

Я сделал это по приведенному выше коду, но работал не так, как ожидалось. Все поля ввода по-прежнему пусты. Я хочу иметь некоторые значения по умолчанию в поле ввода моей формы.


person Subrato Patnaik    schedule 11.10.2020    source источник


Ответы (2)


Проблема в том, что во время первого рендеринга users - это начальное значение ловушки useState, равное null. Значение изменяется только после завершения запроса axios.get(), то есть после первоначального рендеринга. Это означает, что значение по умолчанию, переданное в useForm, равно null.

В документации по defaultValues ​​ говорится следующее:

Важно: defaultValues кэшируется при первом рендеринге в настраиваемом обработчике. Если вы хотите сбросить defaultValues, вам следует использовать reset api.

Итак, вам просто нужно использовать reset, чтобы вручную сбросить форму до значений, которые вы получаете. В документации для reset говорится следующее:

Примечание: вам нужно будет передать defaultValues в useForm, чтобы сбросить значение компонентов контроллера.

Однако из документации неясно, достаточно ли null в качестве значений по умолчанию или вам нужно передать ему правильный объект с полями для каждого ввода. Чтобы не рисковать, предположим, что это последнее.

Код для этого будет выглядеть примерно так:

function LoginFile() {
  const [users, setUsers] = useState({ email: "", firstname: "" });

  const { register, handleSubmit, errors, reset } = useForm({
    defaultValues: users,
  });

  useEffect(() => {
    axios.get("http://localhost:4000/users/1").then((res) => {
      setUsers(res.data);
      reset(res.data);
    });
  }, [reset]);

  useEffect(() => {
    console.log(users);
  }, [users]);

  return (
    <div>
      <form onSubmit={handleSubmit(onSubmit)}>
        Email <input type="email" name="email" ref={register} />
        <br />
        firstname <input name="firstname" ref={register} />
        <br />
        <input type="submit" />
      </form>
    </div>
  );
}

Кроме того, если единственная причина для хука useState - сохранить значение для defaultValues, оно вам вообще не нужно, и вы можете очистить код до следующего вида:

function LoginFile() {
  const { register, handleSubmit, errors, reset } = useForm({
    defaultValues: { email: "", firstname: "" },
  });

  useEffect(() => {
    axios.get("http://localhost:4000/users/1").then((res) => {
      reset(res.data);
    });
  }, [reset]);

  return (
    <div>
      <form onSubmit={handleSubmit(onSubmit)}>
        Email <input type="email" name="email" ref={register} />
        <br />
        firstname <input name="firstname" ref={register} />
        <br />
        <input type="submit" />
      </form>
    </div>
  );
}
person cbr    schedule 11.10.2020
comment
Будет ли reset(res.data) сбрасывать значение defaultValue для данных пользователей API, таких как {email: "[email protected]", firstname: "subrato"}? Я спрашиваю этого bcz, мое мышление таково, что сброс означает пустое поле ввода. - person Subrato Patnaik; 11.10.2020
comment
В документации по reset говорится: Вы можете передавать значения в качестве необязательного аргумента в сбросить форму до значений по умолчанию.. - person cbr; 11.10.2020
comment
У меня есть id ключ в данных моего пользователя. Каким будет значение id по умолчанию, когда мы определим их в useForm? Это нормально с {id: 0, email; "", firstname:""}? Я использую ваш первый подход. - person Subrato Patnaik; 12.10.2020
comment
Ага, эта работа. Я заметил одну вещь, которой мне нравится делиться, когда я устанавливаю состояние как null. Он показывает мне ошибку, подобную cannot read property of "email" which is null', но когда я устанавливаю состояние как [], в полях ввода отображаются пустые значения. - person Subrato Patnaik; 12.10.2020

Это определенно сработало. Используя API сброса и UseEffect.

Начиная с пустых жало как значений по умолчанию и обновляя их как эффекты при сбросе. Вот мой код. Здесь также использовался TypeScript с Ionic ...

const { control: editControl, handleSubmit: editSubmit, reset } = useForm<EditFormType>({
      defaultValues: {
         question: "",
         optionA: "",
         optionB: "",
         optionC: "",
         optionD: "",
      }
   });

   useEffect(() => {
      let defaults ={
         question: editQuestion?.body,
         optionA: editQuestion?.options[0].body,
         optionB: editQuestion?.options[1].body,
         optionC: editQuestion?.options[2].body,
         optionD: editQuestion?.options[3].body,
      }
      reset(defaults)
   }, [editQuestion, reset])

person Ubaezuonu Toby    schedule 12.06.2021