2016-03-09 17 views
11

Thực tiễn/mẫu tốt nhất làm cho lĩnh vực nguồn dữ liệu phản ứng trong ứng dụng gốc phản ứng là gì? Đặc biệt là đối với presentational and container components pattern?Realm & React Native - Phương pháp hay nhất để triển khai tự động cập nhật?

Dưới đây là một ví dụ mà tôi muốn thực hiện phản ứng: Realm with React Native

Các docs on auto-updates/change-events là một chút mỏng và official example không tận dụng tính năng này (theo tôi biết).

Trả lời

13

Bạn có thể làm cho ví dụ của mình phản ứng bằng cách đăng ký các sự kiện và cập nhật ui khi bạn nhận được sự kiện thay đổi. Ngay bây giờ các sự kiện chỉ được gửi khi ghi các giao dịch được cam kết, nhưng các sự kiện thay đổi hạt mịn hơn sẽ được thêm vào trong tương lai. Còn bây giờ bạn có thể thêm các nhà xây dựng sau đây để cập nhật ui vào những thay đổi:

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

Bạn cần phải giữ được một trường hợp Realm để giữ cho các thông báo còn sống, và bạn có thể sử dụng ví dụ Realm này trong suốt phần còn lại của các thành phần.

Thay vì gọi forceUpdate, bạn thay vì có thể thiết lập trạng thái hay đạo cụ của thành phần trong lắng nghe sự kiện để kích hoạt làm mới, như vậy:

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

Cảm ơn @Ari, làm cách nào tôi có thể đặt đạo cụ thành người nghe sự kiện ?. Thay thế 'this.forceUpdate()' bằng 'super (props)'? – ThorbenA

+0

Ví dụ, bạn có thể muốn gọi 'setState' thay thế. Thay vì tính toán 'dogProp' trong' render', bạn sẽ đặt nó trong 'state' sẽ tự động kích hoạt tái render. Một cái gì đó như 'this.setState ({dogProp: this.realm.objects ('Dog'). Length})'. Bạn cũng sẽ muốn thực hiện 'getInitialState'. – Ari

+0

cảm ơn một lần nữa @Ari. Bất kỳ cách nào để làm điều đó mà không cần giới thiệu trạng thái thành phần cục bộ? (Tôi đang sử dụng Redux) – ThorbenA

7

Tôi nghĩ @Ari đã cho tôi một câu trả lời tốt cho redux folks khi tôi cũng đang đấu tranh. Tôi không chắc chắn nếu nó không thay đổi đủ nhưng nó hoạt động!

Tôi đang đơn giản gửi đi getVehicles hành động bên trong addListener và nó chỉ hoạt động!

Dưới đây là thành phần giao diện người dùng có hàm tạo nên sự kỳ diệu!

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

 
    } 
 
}

Dưới là db/mô hình tập tin sử dụng hết có ở các nhà xây dựng.

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

Dưới là những hành động/tập tin phương tiện, mà được cử trong các nhà xây dựng ở trên.

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

 
export function getVehicles() { 
 

 
    const vehicles = queryVehicle(); 
 

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

Dưới là chức năng queryVehicle của tôi mà không được truy vấn gọi là trong tập tin hành động trên.

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

từ chối trách nhiệm Tôi không biết nếu mã này trông đủ bất biến, hoặc sau tốt nguyên nhân thực hành Redux Tôi chỉ bắt đầu với Redux để cho tôi một số ý kiến ​​tư vấn nếu tôi đang làm gì đó sai.

Tôi cũng sẽ đoán việc triển khai reducer sẽ không quan trọng nhiều ở đây.

1

Gần đây đã gặp sự cố với Tự động cập nhật danh sách Realm của Listm. Khi các hàng ListView có chiều cao khác nhau, bạn có thể nhận chồng chéo lên các hàng trong giao diện người dùng. Dưới đây là cách duy nhất tôi có thể có được ListView để tái render mà không gây ra chồng chéo UI. Nó có vẻ hơi "bẩn" đối với tôi, vì vậy nếu có một cách tốt hơn, tôi hoan nghênh đầu vào. Nhưng điều này đang hoạt động hoàn hảo cho đến nay; trong trường hợp bất kỳ ai khác gặp sự cố này.

Về cơ bản nó chỉ lau các nguồn dữ liệu, sau đó chèn nó một lần nữa bằng cách sử dụng callback setstate khi có insertions hoặc deletions, nhưng modifications đơn giản là lăn qua và tự động cập nhật.

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)}); 
    } 
}); 
Các vấn đề liên quan