Realm & React Native - Лучшая практика для внедрения автоматических обновлений?

Каковы лучшие практики/шаблоны, которые превращают realm в реактивный источник данных в ответном родном приложении? Специально для шаблона презентационных и контейнерных компонентов?

Вот пример, который я бы хотел сделать реактивным: Realm with React Native

Документы для автообновлений/изменений-событий немного тонкие и официальный пример не используйте эту функцию (насколько мне известно).

Ответ 1

Вы можете сделать свой пример реактивным, подписавшись на события и обновив ui, когда вы получите событие изменения. Прямо сейчас события отправляются только при совершении транзакций записи, но в будущем будут добавляться более мелкие изменения. Теперь вы можете добавить следующий конструктор для обновления ui при изменениях:

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

Вам нужно удержать экземпляр Realm, чтобы сохранить уведомления в живых, и вы можете использовать этот экземпляр Realm во всем остальном компоненте.

Вместо вызова 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()
  });
}

Ответ 2

Я думаю, @Ari дал мне хороший ответ для redux людей, так как я тоже борется. Я не уверен, что он является неизменным, но он работает!

Я просто отправляю getVehicles действие внутри addListener, и он просто работает!

Ниже находится компонент пользовательского интерфейса, функция-конструктор которого делает магию!

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

    }
} 

Ответ 3

Недавно возникла проблема с автоматическим обновлением Realm ListView. Когда строки ListView имеют разную высоту, вы можете получить перекрытие строк в пользовательском интерфейсе. Ниже был единственный способ, с помощью которого ListView можно было повторно визуализировать, не вызывая перекрытия пользовательского интерфейса. Мне кажется немного "грязным", поэтому, если есть лучший способ, я приветствую вход. Но пока это прекрасно работает; если кто-нибудь еще столкнется с этой проблемой.

В основном, он просто стирает dataSource, а затем вставляет его снова, используя обратный вызов setState, когда есть insertions или deletions, но 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)});
   }
});