如何使用 Realm 项目文件组织 React Native?

Posted

技术标签:

【中文标题】如何使用 Realm 项目文件组织 React Native?【英文标题】:How to organize React Native with Realm project files? 【发布时间】:2017-03-04 20:53:20 【问题描述】:

我选择了在我的 React Native 应用程序中存储数据的领域。我不明白,如何在我的项目中组织文件。文档只为一个组件提供了简单的代码。但是我需要针对不同组件的数据库的不同部分。

我在一个存储库中看到,所有方案都传递到“configureRealm.js”文件中的数组:

new Realm(schema: [Dogs, Cats]);

我还发现,例如,我可以将不同的方案放在“方案”目录中,然后将它们导入到我需要的地方。

例如在“Cats.js”中我可以做的反应组件:

import Cats from 'schemes/Cats';

this.realm = new Realm(schema: [Cats]);

并在“Dogs.js”中导入狗并使用此方案初始化领域。

但我不确定首先和我的方式。组织领域反应原生应用程序的正确和最佳方式是什么?

【问题讨论】:

你使用redux吗?如果是这样,请确保您可以解决来自领域+不可变配对的性能问题。 【参考方案1】:

我最近开始像这样组织我的应用程序/数据结构,在与领域打交道时,从比我聪明得多的人那里得到了一些指导:) 我没有详细介绍领域最初是如何创建的,因为我假设您已经在处理它。这只是组织/分区开发的一个非常坚固的结构。希望对您有所帮助!

.App
    ├──Assets
    ├──Data
    |   ├──Db
    |   |   ├──Db.js
    |   |   ├──DbHelper.js
    |   ├──Models
    |   |   ├──ModelA.js
    |   |   ├──ModelB.js
    |   |   ├──ModelC.js
    |   ├──Queries.js
    ├──Scenes
    |   ├──App.js
    |   |   ├──(all other scene/view components)

--Models 目录包含我所有的模式,像这样单独分解:

import Realm from 'realm';
export default class ModelA extends Realm.Object 
ModelA.schema = 
    name: 'ModelA',
    primaryKey: 'id',
    properties: 
        one: type: 'int', optional: true,
        two: 'string',
        three: type: 'string', optional: true,
    

--在Db.js 中,我保留了所有标准的Realm 相关方法。 createRealm()write()close()insert(),还有一个通用的查询方法,像这样:

query(model: string, filter?: string) 
    let results = this.realm.objects(model);
    if(filter) 
        return results.filtered(filter);
    
    return results;

--DbHelper.js 然后导入Db.js 和我所有的模型。它使用来自Db.js 的标准方法处理我的数据库实例的设置和获取,如下所示:

import Db from 'App/Data/Db/Db';
import ModelA from 'App/Data/Models/ModelA';
import ModelB from 'App/Data/Models/ModelB';
import ModelC from 'App/Data/Models/ModelC';

class DbHelper 

    modelSchema = [
        ModelA,
        ModelB,
        ModelC
    ];

    activeInstancePath = (myLocalRealmPath)

    getInstance(): Db 
        let instance: Db = this.activeInstancePath;
        if(!instance) 
            throw new Error('DbHelper.js :: Active Instance Not Set!');
        
        return instance;
    

    /* note: this is where you would also setInstance and define a constant, or other method for the instance path */

--Queries.js 然后导入DbHelper.jsQueries.js 包含我针对特定应用程序相关数据查询的所有方法。 Queries.js 是我需要导入到我的 Scene 组件中的所有内容,以获取领域数据。我的Queries.js 看起来像这样:

import DbHelper from 'App/Data/Db/DbHelper';

class Queries 

    /* a typical query */
    getSomeDataFromModelA(filterValue: string = null) 
        let filter = null;
        if (filterValue) 
            filter = `two = $filterValue`;
        
        let results = DbHelper.getInstance()
            .query('ModelA', filter);

        return results;
    

    /* return some JSON data that we originally stored in the Realm as a string */
    getSomeJsonData() 
        let results = DbHelper.getInstance()
            .query('ModelB');

        if(results.length) 
            let parsed = JSON.parse(results[0].objectA);
            return parsed.objectB;
        
        return null;
    

export default new Queries();

--App.js。所以现在,在我的应用场景中,我会简单地做这样的事情:

import React,  Component  from 'react';
import  View, Text  from 'react-native';
import Queries from 'App/Data/Queries';

class App extends Component 

    constructor(props) 
        super(props);

        // Get Some Realm Data!
        let modelAData = Queries.getSomeDataFromModelA()
        let someJsonData = Queries.getSomeJsonData();

        // Set Initial state
        this.state = 
            modelData: modelAData,
            jsonData: someJsonData
        
    

    componentDidMount() 
        console.log(this.state.modelData);
    

    render() 
        return(
            <View>
                <Text>this.state.jsonData.objectKey</Text>
            </View>
        );
    


export default App;

【讨论】:

有趣。我想做这样的事情,但它变得更加复杂,因为当您与 Realm 对象服务器同步时,Realm 实例是异步的并作为 Promise 返回,因此您需要“一直保持 Promise” . 另外,快速提问:为什么在Queries 中同时导入DbDbHelperDbHelper 已经导入 Db?谢谢。 @Marklar 是的,您希望查询是单例。所以你会像这样导出它:export default new Queries(); 我将更新答案以包含该行。 @Marklar 是的,这个项目使用了多个领域。我通常为一个项目使用至少两个领域。一个用于应用程序数据,另一个用于应用程序设置,我想与应用程序一起分发并用于全局设置,例如appInitialized 状态。如果您不想要多个领域,只需将getInstance 更改为getRealm 或类似的东西。并且不要担心设置任何activeInstancePath,因为您只有一条路径。 @fostertime - 你们介意分享一段用于打开远程领域的代码吗?您如何访问数据?我有一个 redux 商店,实际上试图通过记录用户、将用户对象保存在我的 redux 商店中并将该用户传递给 getInstance 函数来绕过整个异步内容,但这似乎不起作用&我必须在登录操作中初始化领域。不幸的是,我无法理解这一点。【参考方案2】:

在 Realm github repo 的示例中,所有模型都被定义并从单个文件中导出:https://github.com/realm/realm-js/blob/master/examples/ReactExample/components/realm.js

那么这在整个应用程序中都是必需的,并根据需要使用。

【讨论】:

不幸的是,该示例已过时并且没有显示与 Realm.open 的异步操作

以上是关于如何使用 Realm 项目文件组织 React Native?的主要内容,如果未能解决你的问题,请参考以下文章

如何组织他的项目 React(没有 Redux)的文件?

在React Native App上打开Realm Studio

React Native Realm 数据库:如何从写入命令返回承诺?

如何修复“RealmObject 不能作为函数调用”realm-js 错误?

如何在带有 Typescript 的 React 项目中组织类型定义

如何在 iOS 项目中正确配置 Realm DB 文件 (<db_name>.realm) 的路径?