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
- Dan Abramov says this pattern (context module functions) may help improve performance
- KCD: Authentication in React Applications