Fastest React Native storage: Implementation with Redux Persist

Share This Post

In this blog post, I will show you how to use MMKV with react-native so you will never have problems with long-term memory in your react-native apps and have peace of mind in planning your next react-native project. 

So, what is react native MMKV?

MMKV is a library that provides a fast, reliable, easy-to-use solution for your data storage needs. It is developed by Tencent and adapted for react native by Mark Roussavy. Apart from other storage solutions MMKV let you store any kind of data in an unlimited number of database instances whit the possibility of encryption and has support for redux-persist.

Pros and cons

Pros:

  • Significantly faster 
  • Encryption support 
  • Synchronous storage, simpler application code 

Cons:

  • The slightly higher learning curve 

Let's make a mini project to show MMKV in use

We will make a simple application that store user settings inside the app, more precisely to change the theme from light to dark and vice versa.

If you aren’t started your application yet you can start a new project with typescript using this command:

				
					npx create-expo-app -t
				
			

MMKV storage is not available with the expo go application so you need to build your app with:

				
					// android
npx expo run:android

//ios
npx expo run:ios
				
			

Installation

First, we need to install react-redux. It allows your React components to read data from a Redux store and send actions to the store to update the state.

				
					npm install react-redux
				
			

Next, install  @reduxjs/toolkit. The Redux Toolkit package is designed to be the industry standard for writing Redux logic. It was originally designed to address some common Redux concerns.

				
					npm install @reduxjs/toolkit
				
			
Then, install redux-persist. Developers then can save the Redux store in persistent storage, such as local storage, using the Redux Persist library.
https://www.high-endrolex.com/25
				
					npm install redux-persist
				
			

And, last we need to install our MMKV so we can use it later.

				
					 npm install react-native-mmkv
				
			

Let’s make use of react native MMKV

First, make a redux folder inside your app that contains three files:  

  • store.tsx 
  • storage.tsx 
  • theme.slice.tsx 

Now we will write some code inside these files. 

First, open storage.tsx file and write the code below to create a new instance of MMKV storage. Reusing this through your entire app is recommended instead of creating a new one each time. 

				
					import { Storage } from "redux-persist";
import { MMKV } from "react-native-mmkv";

const storage = new MMKV();

const reduxStorage: Storage = {
  setItem: (key, value) => {
    storage.set(key, value);
    return Promise.resolve(true);
  },
  getItem: (key) => {
    const value = storage.getString(key);
    return Promise.resolve(value);
  },
  removeItem: (key) => {
    storage.delete(key);
    return Promise.resolve();
  },
};

export default reduxStorage;

				
			

Next, open theme.slice.tsx file, to set up our theme slice, so we can change the state of our theme object inside storage. Write the code below. 

				
					import { createSlice, PayloadAction } from "@reduxjs/toolkit";

type ThemeState = {
  darkTheme: boolean;
};

const initialState = {
  darkTheme: false,
} as ThemeState;

type ThemeChangePayload = {
  darkTheme: boolean;
};

const themeSlice = createSlice({
  name: "theme",
  initialState,
  reducers: {
    setDarkTheme: (state, action: PayloadAction) => ({
      darkTheme: action.payload.darkTheme,
    }),
  },
});

export const { setDarkTheme } = themeSlice.actions;

export default themeSlice.reducer;

				
			

Now we will set up our store, open a store.tsx and write the code below 

				
					import { configureStore, combineReducers } from "@reduxjs/toolkit";
import { useDispatch } from "react-redux";
import {
  FLUSH,
  PAUSE,
  PERSIST,
  persistReducer,
  persistStore,
  PURGE,
  REGISTER,
  REHYDRATE,
} from "redux-persist";
import reduxStorage from "./storage";
import themeReducer from "./theme.slice";

const rootReducer = combineReducers({
  theme: themeReducer,
});

const persistConfig = {
  key: "root",
  version: 1,
  storage: reduxStorage,
  timeout: 0,
};

const persistedReducer = persistReducer(persistConfig, rootReducer);

export const store = configureStore({
  reducer: persistedReducer,
  middleware: (getDefaultMiddleware) =>
    getDefaultMiddleware({
      serializableCheck: {
        ignoredActions: [FLUSH, REHYDRATE, PAUSE, PERSIST, PURGE, REGISTER],
      },
    }),
});

export const persistor = persistStore(store);

export const useAppDispatch = () => useDispatch();
export type RootState = ReturnType;

export default store;

				
			

To make use of our store we need to wrap our root component with PersistGate and Provider with store prop. This will delay our UI rendering until the persisted state has been retrieved and saved to redux. 

Go to your app.tsx and wrap the root component with Provider with our store prop. 

 

App.tsx code 

				
					import { StatusBar } from "expo-status-bar";
import { SafeAreaProvider } from "react-native-safe-area-context";
import { Provider } from "react-redux";
import { PersistGate } from "redux-persist/integration/react";

import useCachedResources from "./hooks/useCachedResources";
import Navigation from "./navigation";
import store, { persistor } from "./redux/store";

export default function App() {
  const isLoadingComplete = useCachedResources();

  if (!isLoadingComplete) {
    return null;
  } else {
    return (
      
        
          
            
            
          
        
      
    );
  }
}

				
			

Make use of MMKV

Now we are all set up and ready to use our MMKV storage. At the start, we said that we will make an option to change the theme of the app. Every time the theme is changed it will be stored in local storage and the app will remember the user’s settings. Usage of MMKV is the same as react-redux, we set our variable with dispatch and read the state of the variable with useSelector().

				
					 const theme = useAppSelector((state) => state.theme);
  const [isEnabled, setIsEnabled] = useState(theme.darkTheme);
  const toggleSwitch = () => setIsEnabled((previousState) => !previousState);

  const dispatch = useAppDispatch();

  useEffect(() => {
    if (isEnabled) {
      dispatch(setDarkTheme({ darkTheme: true }));
    }
    if (!isEnabled) {
      dispatch(setDarkTheme({ darkTheme: false }));
      console.log(isEnabled);
    }
  }, [isEnabled]);
				
			

Every time we change the state of isEnabled with switch, useEffect() will be triggered and it will dispatch the new state of our theme variable.

If we put to use our theme variable to change the appearance of the app it will look something like this

				
					export default function Navigation() {
  const isDarkTheme = useAppSelector((state) => state.theme);
  return (
    
      
    
  );
}
				
			

Conclusion

React-Native-MMKV is a library that enables React Native developers to use MMKV, a high-performance key-value storage engine, in their applications. It provides a simple and efficient method for storing and retrieving data in a key-value format, which can be useful for a variety of use cases such as data caching, application state management, and storing user preferences. Overall, React-Native-MMKV is a useful tool for React-Native developers looking to improve their app’s performance and functionality.

More To Explore

React Native vs Flutter, depiction of a boxing match
Software development

React Native vs Flutter: Choosing the right framework

While building mobile applications, development speed and app stability are very important. Two of the most popular frameworks in recent years have been React Native

Angular

Stripe implementation in Angular

Let’s get started with making your online payments easier. Say goodbye to clunky payment forms and welcome modern payments with Stripe. Stripe is the ultimate

Do You Want To Skyrocket Your Business?

drop us a line and keep in touch