如何使用useEffect()更改React-Hook-Form defaultValue?

时间:2020-06-07 08:16:03

标签: javascript reactjs react-hooks react-hook-form

我正在创建一个页面供用户使用React-Hook-Form更新个人数据。 页面加载后,我使用useEffect来获取用户当前的个人数据并将其设置为表单的默认值。

我将获取的值放入defaultValue的{​​{1}}中。 但是,它只是没有显示在文本框中。 这是我的代码:

<Controller />

被调用的API运行良好,并且该值实际上设置为import React, {useState, useEffect, useCallback} from 'react'; import { useForm, Controller } from 'react-hook-form' import { URL } from '../constants'; const UpdateUserData = props => { const [userData, setUserData] = useState(null); const { handleSubmit, control} = useForm({mode: 'onBlur'}); const fetchUserData = useCallback(async account => { const userData = await fetch(`${URL}/user/${account}`) .then(res=> res.json()); console.log(userData); setUserData(userData); }, []); useEffect(() => { const account = localStorage.getItem('account'); fetchUserData(account); }, [fetchUserData]) const onSubmit = async (data) => { // TODO } return ( <div> <form onSubmit={handleSubmit(onSubmit)}> <div> <label>User Name:</label> <Controller as={<input type='text' />} control={control} defaultValue={userData ? userData.name : ''} name='name' /> </div> <div> <label>Phone:</label> <Controller as={<input type='text' />} control={control} defaultValue={userData ? userData.phone : ''} name='phone' /> </div> <button>Submit</button> </form> </div> ); } export default UpdateUserData;状态。

userData

我还尝试{ name: "John", phone: "02-98541566" ... } 中的模拟数据来setUserData,但它也不起作用。 我上面的代码有什么问题吗?

6 个答案:

答案 0 :(得分:22)

@tam 的回答是使其与 6.8.3 版一起工作所需的一半。

您需要提供默认值而且还要使用Effect来重置。如果您有一个用另一个实体重新加载的表单,则需要这种特殊的区别。我在 CodeSanbox here 中有一个完整的示例。

简而言之: 您需要在 userForm 中定义默认值。

 const { register, reset, handleSubmit } = useForm({
    defaultValues: useMemo(() => {
      return props.user;
    }, [props])
  });

然后你需要倾听潜在的变化。

  useEffect(() => {
    reset(props.user);
  }, [props.user]);

代码沙盒中的示例允许在两个用户之间进行交换并让表单更改其值。

答案 1 :(得分:10)

setValue对我不起作用。或者,您可以使用重置方法。我在下面共享一个工作代码块。我希望它对您有用。

  ...
  /* registered address */
  const [registeredAddresses, setRegisteredAddresses] = useState([]);
  
  const { register, errors, handleSubmit, reset } = useForm<FormProps>({
    validationSchema: LoginSchema,
  });

  /**
   * get addresses data
   */
  const getRegisteredAddresses = async () => {
    try {
      const addresses = await AddressService.getAllAddress();
      setRegisteredAddresses(addresses);
      setDataFetching(false);
    } catch (error) {
      setDataFetching(false);
    }
  };

  useEffect(() => {
    getRegisteredAddresses();
  }, []);

  useEffect(() => {
    if (registeredAddresses) {
      reset({
        addressName:
          registeredAddresses: registeredAddresses[0].name,

        tel: registeredAddresses[0].contactNumber,
      });
    }
  }, [registeredAddresses]);

  ...

答案 2 :(得分:8)

因此,使用setValue(https://react-hook-form.com/api#setValue)从useForm导入setValue函数:

    const { handleSubmit, control, setValue} = useForm({mode: 'onBlur'});

然后在收到userData后与用户数据一起调用:

  useEffect(() => {
    if (userData) {
      setValue([{ name: userData.name }, { phone: userData.phone }]);
    }
  }, [userData]);

您可以从表单中删除默认值。我希望这行得通!

答案 3 :(得分:6)

虽然这篇文章已经发布了 2 个月,但我今天偶然发现了这个问题,并寻找了几种方法来解决这个问题。我想出的最有效的方法是使用 useMemo 设置默认值,如下所示:

const { control, errors, handleSubmit } = useForm({
    reValidateMode: 'onChange',
    defaultValues: useMemo(() => yourDefaultValues, [yourDefaultValues]),
});

这允许您在表单中正确设置值,如果您碰巧有字段数组(这就是我的情况),则无需多次实现。

这也适用于使用官方文档中的 advanced smart form component exemple。如果您有任何问题,请告诉我!

答案 4 :(得分:2)

这适用于嵌套对象(我使用的是 6.15.1 版)

     useEffect(() => {
      for (const [key, value] of Object.entries(data)) {
        setValue(key, value, {
          shouldValidate: true,
          shouldDirty: true,
        });
       }
     },[data])

答案 5 :(得分:0)

@tommcandrew的 setValue 参数格式对我不起作用。

这种格式可以做到:

useEffect(() => {
  const object = localStorage.getItem('object');
  setValue("name", object.name);
}, [])