Published: September 19 2021

React Hook Form - Set form values in useEffect hook after async data load

Tutorial built with React 17.0.2 and React Hook Form 7.15.3

This is a quick example of how to set field values in a React Hook Form after loading data asynchronously (e.g. from an API request) with a useEffect() hook.

The solution is to use the reset function from the React Hook Form library to set the form values after the data is loaded (e.g. reset(user)).

Reset and form default values

Calling the reset function with an object (e.g. reset(user)) will update the defaultValues of the form with the values from the object, so subsequent calls to reset() (without params) will use the new default values.


Example React Hook Form that loads user data into fields

This is an example React Hook Form with a few basic user fields to demonstrate loading data and setting form values after the React component is mounted with a couple of useEffect hooks.

(See on StackBlitz at https://stackblitz.com/edit/react-hook-form-set-form-values-in-useeffect)


App Component with React Hook Form

This is the code from the above example React App component, the first useEffect() hook loads the user data into the React component user state, simulating an async API request by calling setTimeout() with a one second delay. The second useEffect() hook executes when the user state changes to update the React Hook Form values by calling reset(user).

While the user is loading ({!user && ... }) a loading spinner is displayed, after the user is loaded ({user && ... }) the React Hook Form is rendered with the user details set.

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

function App() {
    // get functions to build form with useForm() hook
    const { register, handleSubmit, reset } = useForm();

    // user state for form
    const [user, setUser] = useState(null);

    // effect runs on component mount
    useEffect(() => {
        // simulate async api call with set timeout
        setTimeout(() => setUser({ title: 'Mr', firstName: 'Frank', lastName: 'Murphy' }), 1000);
    }, []);

    // effect runs when user state is updated
    useEffect(() => {
        // reset form with user data
        reset(user);
    }, [user]);

    function onSubmit(data) {
        // display form data on submit
        alert('SUCCESS!! :-)\n\n' + JSON.stringify(data, null, 4));
        return false;
    }

    return (
        <div className="card m-3">
            <h5 className="card-header">React Hook Form - Set Form Values in useEffect Example</h5>
            <div className="card-body">
                {user &&
                    <form onSubmit={handleSubmit(onSubmit)}>
                        <div className="form-row">
                            <div className="form-group col">
                                <label>Title</label>
                                <select name="title" {...register('title')} className="form-control">
                                    <option value=""></option>
                                    <option value="Mr">Mr</option>
                                    <option value="Mrs">Mrs</option>
                                    <option value="Miss">Miss</option>
                                    <option value="Ms">Ms</option>
                                </select>
                            </div>
                            <div className="form-group col-5">
                                <label>First Name</label>
                                <input name="firstName" type="text" {...register('firstName')} className="form-control" />
                            </div>
                            <div className="form-group col-5">
                                <label>Last Name</label>
                                <input name="lastName" type="text" {...register('lastName')} className="form-control" />
                            </div>
                        </div>
                        <div className="form-group">
                            <button type="submit" className="btn btn-primary mr-1">Submit</button>
                            <button type="button" onClick={() => reset()} className="btn btn-secondary">Reset</button>
                        </div>
                    </form>
                }
                {!user &&
                    <div className="text-center p-3">
                        <span className="spinner-border spinner-border-lg align-center"></span>
                    </div>
                }
            </div>
        </div>
    )
}

export { App };

 


Need Some React Hook Form Help?

Search fiverr for freelance React Hook Form developers.


Follow me for updates

On Twitter or RSS.


When I'm not coding...

Me and Tina are on a motorcycle adventure around Australia.
Come along for the ride!


Comments


Supported by