Keeping React Native app data global without Redux

Taimoor Khan
4 min readMar 18, 2018
React — Redux data flow

Although undoubtedly, Redux is by far the most appropriate framework you should always be considering for your React/React Native applications. Because, React/React Native and Redux compliments each other so much that they are considered to be a so tightly knit solution for your in-app data management.

However, still I challenged myself to find an alternative way where we could keep in-app React Native API fetched data global for all the components involved for that application, so each component either a child or sibling could access to the data at any level of the component tree.

We are going to leverage mobile device local caching and file system to keep our API fetched data global for every component within our React Native application. This may sound little over whelming at the start but as soon as boil down the code line by line it would make a lot of sense and it is not that complicated.

Let dive into the code;

Snippet 01 — React Native API fetch function

First things first, we are going to use an npm library called RNFetchBlob for our local device caching and filesystem access. Import the library after npm installing it as shown on the line 2 of snippet 01. Then, create a variable as ‘dirs’ representing file system directory structure into the declared variable as shown on the line 9. Now we are going to create a stateless React Native function as we are only caching the fetched API data into our local mobile device storage (CacheDir). We start with firing a method of RNFetchBlob.config() and set out necessary configuration details, like

path’ — where the data should be cached and in which directory should it be;

fileCache’ — a boolean value to accept should it be cached or not;

appendExt’ — what extension should be appended with the binary/media file has been fetched into your local device.

Once this is done as shown from line 12 to 17 of snippet 01, you are then required to fire the fetch() method passing the first argument as ‘GET’ and other one to be your API url as shown on line 18.

Snippet 02 — React Native Component accessing cached data

We are going to go over the constructor() and componentDidMount() functions of the snippet 02 as rest of the code is self-explanatory and usual React Native codebase.

Lets start with the constructor(), we declared a varaible dataSource initiating a new ListView.DataSource() method. After that we declare the state in the constructor, mapping its key dataSource with our variable dataSource.cloneWithRows([]). We declared the state with an empty array expecting it to be populated with our cached data. The next step is to call fetchPosts() on line 26 of sinppet 02. This is the same function as the one in the snippet 01 file. Once this function is fired in the constructor() we expect that our fetched data was cached into your local mobile CacheDir.

Now we are going to extract the data from the local mobile CacheDir and set our React Native state so that we could render it out on our UI components.

Lets dive into the componentDidMount() code of the snippet 02, firstly we are going to define two routes for our possible application logic to flow into; i.e. for iOS and Android. With iOS platform’s security protocols we do not have the same path of the CacheDir each time we access it so we are going to make our path flexible so that it hit the right path each time we need to access the local mobile cached files. We created a variable called fileUri and assigned the path of our cached file (noticed that the path is actually the iOS simulator’s path and not the real device one, to get your simulator path use console.log(‘PATH_TO_READ’, res.path()) to get your path on Chrome console). The next step is to create an array and using its split function to split the fileUri at ‘/’. Now we are going to create a new variable called filePath and concat dirs.CacheDir with the last index of our array we created ahead of this step as shown on the line 34 of snippet 02. This path is the actual path for your iOS cached files in its local directory structure.

With Android, it is rather simpler as Android platform exposes its local directory structure easily compared to the iOS one. So, for this matter, we shall use a static path for Android cached files path as shown on line 35 of snippet 02 [‘/data/user/0/{com.your-bundle-id}/cache/{projectName}’] please note that you have to change {come.your-bundle-id} with your bundle id and {projectName} with your project name accordingly.

As for now the paths have been taken care of, for both of the platforms, now we are going to use RNFetchBlob.fs.readFile() passing in our respective filePath for either of the platforms as first argument, along with the character code ‘UTF8’ as another argument. Please note that by default it will consider the file as a binary one, so its a best practice to always define your file encoding format.

Next step is to resolve the promise by using .then(), passing in the ‘res’ as response (argument), hence storing the data in JsonData variable by using JSON.parse(res). Next step is to return JsonData so that we could use it in the next promise .then(JsonData). Now we are going to setState with our JsonData (Array data) which will trigger React Native to re-render the view as shown on line 47 of snippet 02.

Once the data (array) is made available to the React Native state, you can use it however you wish in your UI components to render it out on the display.

--

--

Taimoor Khan

FullStack Javascript (React) Engineer. Tech Evangelist and US Patent owner for Cardory.