web-dev-qa-db-fra.com

Realm & React Native - La meilleure pratique pour mettre en œuvre les mises à jour automatiques?

Quelles sont les meilleures pratiques/modèles qui font du domaine une source de données réactive dans une application native react? Spécialement pour modèle de présentation et de composants de conteneur ?

Voici un exemple que j'aimerais rendre réactif: Royaume avec React Native

Les docs sur les mises à jour automatiques/change-events sont un peu minces et le exemple officiel ne fait pas usage de cette fonctionnalité (à ma connaissance).

13
ThorbenA

Vous pouvez rendre votre exemple réactif en vous abonnant à des événements et en mettant à jour l'interface utilisateur lorsque vous recevez un événement change. À l'heure actuelle, les événements ne sont envoyés que lorsque les transactions d'écriture sont validées, mais des événements de changement plus détaillés seront ajoutés ultérieurement. Pour l'instant, vous pouvez ajouter le constructeur suivant pour mettre à jour l'interface utilisateur à la suite des modifications:

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

Vous devez conserver une instance de domaine pour maintenir les notifications actives. Vous pouvez utiliser cette instance de domaine dans le reste du composant.

Au lieu d'appeler forceUpdate, vous pouvez définir l'état ou les accessoires du composant dans l'écouteur d'événements pour déclencher l'actualisation, comme suit: 

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()
  });
}
15
Ari

Je pense que @Ari m'a donné une bonne réponse pour reduxfolks car je me débattais aussi . Je ne sais pas si c'est assez immuable, mais ça fonctionne!

Je répartis simplement l'action getVehicles à l'intérieur de addListener et cela fonctionne!

Ci-dessous est le composant d'interface utilisateur dont la fonction constructeur rend la magie!

//- 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());
        });

    }
} 

En bas est le fichier db/models utilisé dans le constructeur.

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]});

Ci-dessous est le fichier actions/vehicle, qui est envoyé dans le constructeur ci-dessus.

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

export function getVehicles() {

    const vehicles = queryVehicle();

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

Ci-dessous est la fonction queryVehicle qui effectue la requête appelée dans le fichier d'action ci-dessus.

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 };

_ {disclaimer Je ne sais pas si ce code a l'air assez immuable, ou s'il est conforme aux bonnes pratiques de redux, car je commence tout juste avec redux, alors laissez-moi quelques commentaires vous avisant si je fais quelque chose de mal.

Je suppose aussi que la mise en œuvre de reducer n'aurait pas beaucoup d'importance ici.

8
ArchNoob

Récemment rencontré un problème avec la mise à jour automatique de RealView ListView. Lorsque les lignes ListView ont des hauteurs variées, vous pouvez obtenir des chevauchements sur les lignes de l'interface utilisateur. La procédure ci-dessous était le seul moyen d'obtenir de nouveau le rendu de ListView sans provoquer de chevauchement de l'interface utilisateur. Cela me semble un peu "sale", donc s'il y a un meilleur moyen, je serais heureux de recevoir vos commentaires. Mais cela fonctionne parfaitement jusqu'à présent; Si quelqu'un d'autre se heurte à ce problème.

Fondamentalement, il efface simplement la source de données, puis l'insère à nouveau à l'aide du rappel setState lorsqu'il existe insertions ou deletions, mais modifications survolez et mettez à jour automatiquement. 

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