reactjsformspage-refreshtanstackreact-query

Autofill form with user data does not work on Page Reload while using React Query to fetch data


I have a simple form to update user data. I am using React Query in my app. The form autofills successfully with user data and the user update mutation also works fine. The problem arises when I refresh the page. The input fields no longer displays the user data. They are just blank.

I have tried to log the user data. Initially the data is undefined and then it fetches successfully, but the form fields still remain blank.

I tried to look for solutions on the web, but it says localStorage is the only option. But I am not sure if localStorage is the best option.

Here is how my form looks before page refresh: enter image description here

And this is how my form looks like after page refresh: enter image description here

The photo is getting served from assests folder, hence it is still there, but the rest of the user data vanishes.

This this the function for fetching user data:

export const useUser = () => {
  const {
    data: user,
    isPending,
    isFetched,
  } = useQuery({
    queryKey: ["user"],
    queryFn: getCurrentUser,
  });

  return { isPending, user, isFetched };
};

And this is the form:

const UserDetail = () => {
  const { user, isPending: isLoadingUser, isFetched } = useUser();
  const { updateUserMutation, isUpdatingUser } = useUpdateUser();

  const [name, setName] = useState(user?.name);
  const [email, setEmail] = useState(user?.email);

  if (isLoadingUser || user === "undefined") {
    return <Spinner />;
  }

  return (
    <div>
      <form onSubmit={handleSubmit}>
        <div>
          <label className="form__label">Name</label>
          <input
            id="name"
            type="text"
            value={name}
            onChange={(e) => setName(e.target.value)}
            required
            disabled={isUpdatingUser}
          />
        </div>
        <div>
          <label>Email</label>
          <input
            id="email"
            type="email"
            value={email}
            onChange={(e) => setEmail(e.target.value)}
            required
            disabled={isUpdatingUser}
          />
        </div>
      </form>
    </div>
  );
};

Solution

  • I have finally arrived at a solution. So, initially when the user data gets fetched (using useUser hook), it is undefined, but eventually after the fetch is successful the user data shows up.

    Hence during the initial render, the form states are empty, because I have set the initial state as empty. Hence when user is undefined, name and email are undefined as well:

    const [name, setName] = useState(user.name);
    const [email, setEmail] = useState(user.email);
    

    Now, I have made the following changes to the form:

    const UserDetail = () => {
      const { user, isPending: isLoadingUser, isSuccess } = useUser();
      
    
      const [name, setName] = useState("");
      const [email, setEmail] = useState("");
    
      useEffect(() => {
        if (isSuccess) {
          setName(user.name);
          setEmail(user.email);
        }
      }, [name, email, isSuccess]);
    
      if (isLoadingUser) {
        return <Spinner />;
      }
    
      return (
        <div>
          <form onSubmit={handleSubmit}>
            <div>
              <label className="form__label">Name</label>
              <input
                id="name"
                type="text"
                value={name}
                onChange={(e) => setName(e.target.value)}
                required
                />
            </div>
            <div>
              <label>Email</label>
              <input
                id="email"
                type="email"
                value={email}
                onChange={(e) => setEmail(e.target.value)}
                required
                />
            </div>
          </form>
        </div>
      );
    };
    

    I am running a useEffect hook to update the form states when the fetching of data is successful, i.e by utilizing isSuccess returned from useQuery hook:

     const { user, isPending: isLoadingUser, isSuccess } = useUser();
    
    useEffect(() => {
        if (isSuccess) {
          setName(user.name);
          setEmail(user.email);
        }
      }, [name, email, isSuccess]);
    

    These changes would continue to reflect user data on the form after the page reloads.