web-dev-qa-db-ja.com

レルム&Reactネイティブ-自動更新を実装するためのベストプラクティス?

リアクションネイティブアプリでレルムをリアクティブデータソースにするベストプラクティス/パターンは何ですか?特に プレゼンテーションおよびコンテナコンポーネントのパターン

これが私がリアクティブにしたい例です: レルムwith React Native

auto-updates/change-eventsに関するドキュメント は少し薄く、 公式の例 は(私の知る限り)この機能を利用していません。

15
ThorbenA

イベントをサブスクライブし、変更イベントを受信したときにUIを更新することで、例をリアクティブにすることができます。現在、イベントは書き込みトランザクションがコミットされたときにのみ送信されますが、将来的にはよりきめ細かい変更イベントが追加される予定です。今のところ、次のコンストラクターを追加して、変更時にUIを更新できます。

constructor(props) {
  super(props);
  this.realm = new Realm({schema:[dogSchema]})
  this.realm.addListener('change', () => {
    this.forceUpdate()
  });
}

通知を存続させるには、レルムインスタンスを保持する必要があり、コンポーネントの残りの部分全体でこのレルムインスタンスを使用できます。

forceUpdateを呼び出す代わりに、次のように、イベントリスナー内でコンポーネントの状態または小道具を設定して更新をトリガーすることができます。

constructor(props) {
  super(props);

  this.realm = new Realm({schema:[dogSchema]})

  this.state = {...}; // Initial state of component.

  this.realm.addListener('change', () => {
    this.setState({...}); // Update state instead of using this.forceUpdate()
  });
}
16
Ari

私も苦労していたので、@ Ariはreduxの人々に良い答えをくれたと思います。十分に不変かどうかはわかりませんが、動作します!

getVehicles内にaddListenerアクションを簡単にディスパッチしているので、うまくいきます。

以下はコンストラクター関数が魔法をかけるUIコンポーネントです!

//- importing my realm schema
import realm from '../../db/models';
//- Importing my action
import { getVehicles } from './../../actions/vehicle';


@connect((store) => {
    return {
        vehicle: store.vehicle.vehicles
    }
})
export default class Devices extends Component {
    constructor(props) {
        super(props);

        realm.addListener('change', () => {
            props.dispatch(getVehicles());
        });

    }
} 

以下コンストラクターで使用されるdb/modelsファイルです。

import Realm from 'realm';

class VehicleSchema {};

VehicleSchema = {
    name: 'vehicleInfo',
    properties: {
        vehicleName: 'string',
        vehicleNumber: 'string',
        vehiclePassword: 'string',
        vehiclePasswordTrigger: 'bool',
        vehicleType: 'string',
        vehiclePicture: { type: 'data', optional: true }
    }
};

export default new Realm({schema: [VehicleSchema]});

以下はactions/Vehicleファイルであり、上記のコンストラクターでディスパッチされます。

import { queryVehicle } from './../db/queryVehicle';

export function getVehicles() {

    const vehicles = queryVehicle();

    return function(dispatch) {
        dispatch({type: "GOT_VEHICLES", payload: vehicles});
    }
}

以下は、上記のアクションファイルで呼び出されたクエリを実行するqueryVehicle関数です。

import vehicleModel from './models';

const queryVehicle = (queryInfo="vehicleInfo", filter='') => {

    const objects = vehicleModel.objects(queryInfo);

    if(filter.length === 0) return objects;

    let results = objects.filtered(filter);
    return results;


};

export { queryVehicle };

免責事項このコードが十分に不変に見えるかどうか、または適切なreduxプラクティスに従うと、reduxを使い始めたばかりなので、何か間違ったことをしている場合はアドバイスをください。

また、ここではreducerの実装はそれほど重要ではないと思います。

8
ArchNoob

最近、レルムリストビューの自動更新で問題が発生しました。 ListViewの行の高さが異なる場合、UIの行が重複する可能性があります。以下は、UIのオーバーラップを引き起こさずにListViewを再レンダリングする唯一の方法でした。私には少し「汚い」ように思われるので、もっと良い方法があれば、私は入力を歓迎します。しかし、これはこれまでのところ完全に機能しています。他の誰かがこの問題に遭遇した場合に備えて。

基本的には、dataSourceをワイプし、insertionsまたはdeletionsがある場合は、setStateコールバックを使用して再度挿入しますが、modificationsは単にロールスルーして自動更新します。

let feed = this.props.store.feed;

feed.addListener((name, changes) => {
   if (changes.insertions.length || changes.deletions.length) {
       this.setState({dataSource: this.ds.cloneWithRows([])},
           () => this.setState({dataSource: this.ds.cloneWithRows(feed)})
       );
   } else {
        this.setState({dataSource: this.ds.cloneWithRows(feed)});
   }
});
1
fostertime