Search code examples
reactjsreact-reduxreact-routerreact-hooksuse-effect

Easily loading data into React Form only when page loads


I am trying to implement a 'profile details' feature in a React app.

What I would like the page to do when a user navigates here:

  • All stored information from the database for this profile populates into the respective fields
  • If there is no value, the field stays blank.
  • A user can select a field, edit its value (stored in useState hook to have controlled values)
  • User can then submit the form in order to commit these changes to the database.

I am using useState to manage formData and useEffect Hook to pre-populate the fields when the page is rendered (getting values from redux store).

I am also using react router to make this route private, and redirect users that are not authenticated.

Everything works fine, except for my useEffect hook - that gives me tons of trouble:

  useEffect(() => {
    getCurrentProfile();
    if (profile !== null) {
      setFormData({
        location: loading || !profile.location ? '' : profile.location,
        gender: loading || !profile.gender ? '' : profile.gender,
        age: loading || !profile.age ? '' : profile.age,
        bio: loading || !profile.bio ? '' : profile.bio,
      });
    }
  }, [getCurrentProfile, loading]);

Note: the if statement is there to prevent the app from crashing if a non-authenticated user accesses this route. I get a TypeError: Cannot read property 'location' of null if I don't have some kind of blocker from this weird way of updating state.

I run into the following issue:

  1. Current implementation, I get a linter error:

React Hook useEffect has a missing dependency: 'profile'. Either include it or remove the dependency array react-hooks/exhaustive-deps

This "works" the way I want it to. If I enter something, then refresh/change page, the form renders with the updated information. Local state is still controlled by useState hook, as user many change the form and choose not to submit the information to the database.

  1. If I add the profile dependency, any time I enter a value into these fields the page just keeps re-rendering and killing everything I input because its not the previous state of the DB.

Im not understanding why this is happening, or what the best practice is for pre-populating the fields while still making it accessible to be locally controlled state for submission.

This will of course remove the linter error, but it breaks my intended functionality. Is this a problem?

I just want this thing to run after the page is loaded, so that the user knows what the current profile values are.

Any advice? Maybe my entire approach is wrong for what I am trying to do. Happy to provide more details if need be.


Solution

  • Figured it out by refactoring and handling local state in a child component.