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