Reputation: 12428
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:
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;
}
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()} );
}
}
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?
Upvotes: 14
Views: 6696
Reputation: 1493
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();
Upvotes: 17