最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

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

programmeradmin5浏览0评论

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 ponents? 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 ponents and actions, and also to being more loosely coupled from native ponents, 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 ponent:

In the applications root ponent 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 ponents 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?

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 ponents? 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 ponents and actions, and also to being more loosely coupled from native ponents, 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 ponent:

In the applications root ponent 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 ponents 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?

Share Improve this question edited May 20, 2016 at 9:14 itinance asked May 20, 2016 at 9:06 itinanceitinance 12.4k8 gold badges64 silver badges109 bronze badges
Add a ment  | 

1 Answer 1

Reset to default 17

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 ponent you can get the database connection with:

var connection = Database.getConnection();

与本文相关的文章

发布评论

评论列表(0)

  1. 暂无评论