Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ReactNative: best approach to share a sqlite-instance across all components and actions

The story:

In a react-native app we use react-native-sqlite-storage for dealing with sqlite3 both on iOS and Android.

This plugin enable us to deal with native sqlite implementation in that way:

var db = SQLite.openDatabase("test.db".....);

What would be the best approach to share the db-instance across multiple components? To give more details, but this is not part of this question, we use redux and have many action-files. Some of them need access to the database too.

In order to deal with a single opened instance of sqlite across all components and actions, and also to being more loosely coupled from native components, i built a class DataStorage encapsulating the storage-plugin. This class holdes an instance of the sqlite-database (using the react-native-sqlite-storage) and provides convenient methods to the application like "getUserByName()", "getAllItems" and so on.

To avoid multiple instances of this DataStorage class and also its inner sqlite-db-instance, i did the following:

  1. build the DataStorage class
  2. create a global variable residing only in DataStorage.js
  3. export a function sharedDataStorage() to the all the callers which need database access

Code of DataStorage.js

const SQLite = require('react-native-sqlite-storage');

const _dataStorage = null;

export class DataStorage {

    constructor(autoCheckMigration = true, lang = 'en') {
        console.log("DataStorage CTOR called");

        if(_dataStorage !== null) {
            throw 'There is already an instance of DataStorage alive';
        }

        // store this instance in a global variable
        _dataStorage = this;

        this.db = SQLite.openDatabase('myapp.db', '1.0', 'Myapps Database', 5 * 1024 * 1024, this.openCB, this.errorCB);

        if (autoCheckMigration) {
            this.checkDatabaseMigration(lang);
        }
    }

    many_other_convenience_methods_here(...) {}
}

export function sharedDataStorage() {
    return _dataStorage;
}

Applications root component:

In the applications root component i create the database instance calling its constructor.

export default class Application extends React.Component {

    constructor(props) {
        super(props);

        this.setupDatabase();
    }

    render() {
        return (
            <Provider store={store}>
                    <ApplicationContainer />
          </Provider>
        );
    }

    setupDatabase() {
        this.setState( {dataStorage: new DataStorage()} );
    }
}

Some action_...js:

All other components and action-files now must gain access to this DataStorage-Class in this way:

import { sharedDataStorage } from '../data/dataStorage';

...

async function persistContacts(contacts) {
    const dataStorage = sharedDataStorage();

    contacts.forEach( (contact) => {
        dataStorage.persistContact(contact);
    });
}

This way is working pretty fine, although i am not sure, if there are better approaches sharing a database connection in react-native.

Which other possibilities are there?

like image 231
itinance Avatar asked May 20 '16 09:05

itinance


People also ask

How do I use React React Native with SQLite?

React-Native with SQLite 1 Project Configuration. Install node and npm. Install expo-cli globally. Initialize the expo project. ... 2 UI Components with Styling. React functional components will be used to create UI components for the application. ... 3 SQLite Configuration

How to configure SQLite to be used in the application?

Do the following to configure SQLite to your application. Install SQLite as a dev dependency. 2. Import openDatabase function from expo-sqlite api inside the file you intended to use database querying functions. 3.

Is SQLite the best choice for on-device relational storage?

When it comes to storing relational data on-device with minimal overhead, SQLite is the natural choice. It’s fast, rock solid, and has been battle tested for years across a huge array of platforms and devices.

Why choose React Native for embedded data storage?

On this regard, React Native provides the easiest ways of configuring the development environment and get on with your application development. In this article, I'll explain how to configure and develop your own react-native application, additionally, with SQLite for embedded data storage.


1 Answers

I solve in this way:

database.js

'use strict';
import React from 'react';
import SQLite from 'react-native-sqlite-storage';


var database_name = "dbname.db";
var database_version = "1.0";
var database_displayname = "db";
var database_size = 200000;

let conn = SQLite.openDatabase(database_name, database_version, database_displayname, database_size, openDBHandler, errorDBHandler);

class Database  {
    getConnection() {
        return conn;
    }
}

module.exports = new Database();

Next in your component you can get the database connection with:

var connection = Database.getConnection();
like image 52
Marco Avatar answered Nov 07 '22 13:11

Marco