Advanced React Patterns

(User Update Form)
Unnamed
No biography provided
(user#24601)
Big Head

Context Module Functions

Summary: Add the ability for a user to submit data (such as updating its user profile) to a backend. As usual, your app should handle the request success or failure appropriately keeping the end user's experience in mind. Use the Context Module functions pattern for better performance by avoiding unneccessarily component rerenders and comparisons.

  • This user Update Exercise is taken from here
  • In this exercise, you'll have a form that updates the user profile, you'll have to submit the updates to a backend.
  • The request to update will be rejected 50% of the time to simulate network errors.
  • The backend will choose a (bighead) avatar for the user given the provided information. You can create your own algorithm on how to do this but it has to be deterministic.
  • This user profile should be available anywhere in your app
  • When the form is submitted, the user profile will be immediately updated, but when the backend reports that something when wrong, the update will be erased, and the user profile will go back to the latest saved information.
  • There should be a reset, submit, try again button when appropriate, and they should be disabled when appropriate.

Background

A good pattern to use here is Context Module Functions. In a nutshell, the idea have a function that can be exported to be used in conjuction with the dispatch function that your hook exposes. This function accepts the dispatch function (along with other arguments) and calls this dispatch function appropriately.

Here is an example of how this pattern can be applied to a global Counter context. You'd have a module counter-context.js which exports CounterProvider, useCounter and updateCounter. useCounter exposes two properties [state, dispatch]. To update the state of the counter, you'd pass the dispatch to updateCounter along with any other arguments required by the updateCounter function.

For this exercise, I'll have a user-context.js which exports UserProvider, useUser and updateUser. Where userUpdate takes in three arguments: the dispatch function, the current user from the useUser and updates. updates are the contents of the submitted form.The userUpdate function is responsible for communicating the required updates to our backend and updating the saved user depending on the response of the backend. The user is updated by calling the dispatch function.

My Solution

My solution is not really that different to Kent's solution, so it might be better if you go look at that instead.

Here's the user reducer

Here's the context module (with a context module function)

Here's the form component

And here's the user profile card

Note: Here's how my backend computes the profile avatar specification: (1) How you look is determined by the letters of your nickname, (2)The accessories (hat, hat color, shirt color, graphic, shirt) depends on the letters of your bio and previous bio

Notes

Helper methods are object junk that we need to recreate and compare for no purpose other than superficially nicer looking syntax. - Dan Abramov