I’m creating a client-side only mockup of a gym-class management system. I have a models folder with javascript dummy user objects that will provide default user credentials and info. However, I want users to log in (using dummy credentials) and then be able to play around with the functionality by editing personal info, scheduling classes, etc. I do want persistent data across different sessions so I’m using localStorage as the "database". The project is very small so I wasn’t concerned about the storage size limits. Right now, I have programmed it so that logging in sets both the global authorized user state and sets the localStorage with the user object and all of its properties.
When it comes to the actual functionality (such as editing profiles or something), I’m lost on whether I should:
- alter localStorage => then have a useEffect that syncs state with storage changes
- alter state => then have a useEffect that syncs storage with state changes
- just update both
For example, I have a widget component that would track to-dos for admin users. In the user object, I have a nested todos array. So far I’ve programmed it so that when the admin CRUD operates on the todo widget, it updates the user.todos
property in both authState
and localStorage user object. I’m currently just wondering whether there is a "best practice" for these kind of client-side-only mockups.
2
Answers
I would avoid using useEffect unless necessary. It would probably make the most sense to update state immediately for the best user experience, and then in the same event handler, update local storage. I would only pull from local storage on load.
You should apply the second option: "alter state => then have a useEffect that syncs storage with state changes".
The first option "alter localStorage => then have a useEffect that syncs state with storage changes" won’t work because localStorage is non-reactive, meaning that updates to localStorage won’t trigger a React component re-render for the
useEffect
hook to run again and pick up any changes.The third option "just update both" is also ok, but may result in code that is less DRY because you end up duplicating the code/logic that persists changes out to localStorage in each handler that is enqueueing state updates. The
useEffect
hook is a single unit that handles reacting to the state updates enqueued from anywhere.You will use all three:
useState
hook to represent the "source of truth" that users will edit/update. The state will be lazily initialized from localStorage.useEffect
hook to persist React state updates to localStorage.The basic setup/usage will look similar to the following: