Caching your images on react-native with Expo

Jérémie Drouet
Dec 15, 2017 · 3 min read

If you’re using expo to build your mobile applications, you might already know that if you want to keep the wonderful build functionality, you shouldn’t install native plugins. And if you’re familiar with building react-native applications, you might also know that the embedded image caching system is not really what you would expect from it.

To avoid this problem, we’ll implement a simple cache system using redux, redux-saga and the filesystem api given by expo.

Image for post
Image for post

We’ll first start by implementing a reducer that receives the requests to load the images. This reducer will receive 4 different types of actions, one to check if the image is already loaded (only used to launch a side effect), one to start the download, one for when the download is successful and one for when there is an error. The store will contain a list of urls that you are actually loading and a map of already loaded images. When the reducer receives a download action, the url will be added to the list. When the download is successful, the url is removed from the initial list and added to the map with the corresponding location on the file system.

Then, it’s time to implement the saga that will intercept the actions and execute the side effect that downloads an image. To do so, we need to listen every fetch action and then check if the file is already loading. If not, we need to check if the file is already on the file system. If the file is on the file system, we just notify the store to add it in the map, otherwise we download it and, at the end, we notify the store.

Finally, we will implement a SmartImage component that will emit an action to the store when it needs to load the image from the internet. Then, we’ll bind this component to the store in order to notify it when the image is loaded. When put together, the code looks like this:

When everything is implemented, you have a decent cache system that loads your images from your file system.

Few caveats

In this example, the names of the images are provided to the component, but in the real world, you have to resolve the name and the type of the image from the url in order to persist it. To do so, you can just do a hash of the url and use it as a filename.

Sometimes, the image can change without url change. Adding a timestamp to file url before hashing it is a simple way to avoid this issue. That way, each time you modify an image on the server side, you modify the timestamp and the hash is different.

Remember that you use the filesystem of your user to store the files. So take care to remove them when they are not used anymore in order not to fill the user’s device space with your images.

An example would be nice!

The source code of a running example is available on the following link.

You wan’t to try it directly on your phone using expo?

Interested by making an application?

One More Thing Studio

Des conseils, des outils et des bons plans pour devenir…

Thanks to Jérôme Dumont and Iman Zarrabian

Jérémie Drouet

Written by

Craftman, architect and fullstack developer.

One More Thing Studio

Des conseils, des outils et des bons plans pour devenir meilleur en UX, Growth Hacking, Dév, Productivité…

Jérémie Drouet

Written by

Craftman, architect and fullstack developer.

One More Thing Studio

Des conseils, des outils et des bons plans pour devenir meilleur en UX, Growth Hacking, Dév, Productivité…

Medium is an open platform where 170 million readers come to find insightful and dynamic thinking. Here, expert and undiscovered voices alike dive into the heart of any topic and bring new ideas to the surface. Learn more

Follow the writers, publications, and topics that matter to you, and you’ll see them on your homepage and in your inbox. Explore

If you have a story to tell, knowledge to share, or a perspective to offer — welcome home. It’s easy and free to post your thinking on any topic. Write on Medium

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store