Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to change React-Hook-Form defaultValue with useEffect()?

I am creating a page for user to update personal data with React-Hook-Form. Once paged is loaded, I use useEffect to fetch the user's current personal data and set them into default value of the form.

I put the fetched value into defaultValue of <Controller />. However, it is just not showing in the text box. Here is my code:

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;

The called API is working well and the value is actually set to userData state.

{
  name: "John",
  phone: "02-98541566"
  ...
}

I also tried to setUserData with mock data in useEffect(), and it doesn't work either. Is there any problem in my above code?

like image 309
theedchen Avatar asked Jun 07 '20 08:06

theedchen


People also ask

How do I change the default value in React hook form?

The solution is to use the reset() function from the React Hook Form library, if you execute the function without any parameters ( reset() ) the form is reset to its default values, if you pass an object to the function it will set the form with the values from the object (e.g. reset({ firstName: 'Bob' }) ).

How do I set default value in useForm?

You can set an input's default value with defaultValue/defaultChecked (read more from the React doc for Default Values). You can pass defaultValues as an optional argument to useForm() to populate the default values for the entire form, or set values on an individual Controller component via its defaultValue property.

Can we change state in useEffect hook?

Run useEffect on State Change By default, useEffect runs after every render, but it's also perfect for running some code in response to a state change. You can limit when the effect runs by passing the second argument to useEffect.

How does useEffect () hook gets executed?

useEffect() hook runs the side-effect after initial rendering, and on later renderings only if the name value changes.


1 Answers

@tam answer is halfway through what is needed to make it work with version 6.8.3.

You need to provide the default value but also to useEffect to reset. That particular distinction is required if you have a form that you reload with another entity. I have a complete example in CodeSanbox here.

In a nutshell: You need to define your defaultValues in the userForm.

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

Then you need to listen to potential change.

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

The example in the Code Sandbox allows swapping between two users and have the form change its values.

like image 127
Patrick Desjardins Avatar answered Sep 20 '22 23:09

Patrick Desjardins