DEV Community

Lukie Kang
Lukie Kang

Posted on

React Learnings from 2018 - using LocalStorage

Now (from previous posts) we have some grocery store items saving in a remote database, we can leverage localStorage to store the user's order so that it isn't just completely lost when they refresh or close the browser. This post is all about understanding LocalStorage.

Lets break it down the basic questions we will need to answer on the way:

  • What is localStorage
  • When to save to localStorage
  • What to save to localStorage
  • How to save to localStorage
  • How to retrieve from localStorage
  • When to display from localStorage

I think I am going to get really tired of writing localStorage by the end of this post.

What is localStorage?

localStorage or window.localStorage is a read-only property that provides access to a Storage object that is saved between browser sessions for that site. It is the sister of sessionStorage which, as the title says, exists while the page session does. As it uses object notation, it wants things as a key value pair.

This MDN Article explains it in more detail.

How can we use localStorage?

Playing with localStorage is fairly simple:

We can Add by doing a setItem:

localStorage.setItem("myName", "James")

We can Read by doing getItem:

localStorage.getItem("myName")

We can Remove by doing removeItem:

localStorage.removeItem("myName")

You can remove everything with a clear

localStorage.clear()

WHEN to use localStorage

Whenever a user changes thier order we want to send the new value to localStorage. Since React updates a component whenever we make a change to it's state, there is a lifecycle method we can use called componentDidUpdate()

WHAT to save to localStorage

We can't just save just one order object as we are using a different set of orders per store so we need to include the store as the key, and the relevent order as the property. Handily, this is a param provided to us via react router:

componentDidUpdate(){ 
    localStorage.setItem(this.props.match.params.storeId, this.state.order)
    }
Enter fullscreen mode Exit fullscreen mode

Slight gotcha here... Of Objects and Strings

localStorage wants the key and property to be a string, however this.state.order is an object so you will instead see [Object object] how do we fix that?

JSON.stringify(this.state.order)

And conversely, we need to do JSON.parse to bring it back as an object at a later point.

You should now have your order going into localStorage.

Reading the localStorage on Mount

While we can get things into localStorage, when we refresh the page, the order in state is blank again. Thats because the componentDidMount() method, triggers an componentDidUpdate() to nothing. To fix this we need to reinstate localStorage as part of the component mounting:

  1. First pick up the localStorage string from params: const localStorageRef = localStorage.getItem(params.storeId);

  2. Secondly, set the state while converting it to an object this.setState({ order: JSON.parse(localStorageRef)})

Asynchronous issues

Now that we have the order being read on mounting we will encounter an issue.

localStorage is now carrying an order which refers to groceries which, in our previous post, is coming from Firebase. since Firebase is cloud-hosted, it will never be ready before the data from localStorage needs it. It will say something like cannot read Status of undefined

How do we fix that?

The update that contains the information from Firebase only takes a moment to arrive so here it is a case of holding off working on the values till it has loaded. The offending line is in the Order Component:

const isAvailiable = grocery.status === "availiable";

We can change that to:

const isAvailiable = grocery && grocery.status === "availiable"

However, for the split second it takes for the data to arrive, the order will display the messae saying the item is unavailible which is messy, so a smarter way is to simply say:

if(!grocery) return null

This wont render anything till we have the database of groceries ready to go.

Conclusion

Using localStorage is a fairly straightforward process, there is just a few gotchas you need to be aware of. The worse of which is the timing ascpect around accessing the database. A good understanding of lifecycle methods in React helps with this...perhaps thats a post for another time.

Top comments (0)