境界与React Native - 实施自动更新的最佳做法?

时间:2016-03-09 20:53:02

标签: react-native realm

什么是最佳实践/模式,使域成为反应原生应用中的反应数据源?特别是presentational and container components pattern

这是一个我想要反应的例子:Realm with React Native

docs on auto-updates/change-events有点薄,official example没有使用此功能(据我所知)。

3 个答案:

答案 0 :(得分:16)

您可以通过订阅事件并在收到更改事件时更新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()
  });
}

答案 1 :(得分:8)

我认为@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]});

下面是操作/工具文件,它将在上面的构造函数中调度。

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实现在这里并不重要。

答案 2 :(得分:1)

最近遇到了Realm ListView自动更新的问题。当ListView行具有不同的高度时,您可以在UI中的行上获得重叠。下面是我可以让ListView重新渲染而不会导致UI重叠的唯一方法。这似乎有点“肮脏”#34;对我来说,如果有更好的方式,我欢迎投入。但到目前为止,这是完美的。任何其他人遇到这个问题。

基本上它只是擦除dataSource,然后在insertionsdeletions时使用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)});
   }
});