2017-06-02 61 views
0

我有一個反應組件,它有componentWillMount並使用setState方法更新狀態。我正在用對象數組更新狀態變量rideTiles,儘管我沒有獲取用於渲染的ant數據。我通過返回默認true來嘗試shouldComponentUpdate(),仍然組件不會使用更新的值進行呈現。我無法確定發生了什麼問題?setState不改變UI數據

這裏是我的代碼

import React from 'react'; 
import {TouchableOpacity, Image, View, Text, StyleSheet, Dimensions, ScrollView} from 'react-native'; 
import Gradient from '../components/gradient'; 
import Icon from 'react-native-vector-icons/MaterialCommunityIcons'; 
import PRides from '../components/PRides' 
import {GetRequest, GetUrl} from '../lib/net.js'; 
import Realm from '../lib/schemas.js'; 
import sqlite from '../lib/sqlite'; 
import config from '../../config.js'; 
import {DistanceAndTime} from '../lib/geoDistCal.js' 
const AvroCodec = require('avroschema'); 

export default class Rides extends React.Component { 
    static navigationOptions = { 
     label: 'Rides', 
     tabBarIcon:() => (
     <Image 
      source={require('../res/img/icn-ftrlnk2.png')} 
      style={[styles.img]} 
     /> 
    ), 
    } 
    constructor(props){ 
    super(props); 
    this.onRideData = this.onRideData.bind(this); 
    EE.addEventListener(EE.EVENT_TYPES.RIDE_DETAILS, this.onRideData); 
    this.eventCounts = 0; 
    this.insertedCount = 0; 
    this.rideTiles = []; 
    } 
    componentWillMount(){ 
    var self = this; 
    GetRequest(GetUrl(config.glHost + "/gl/users/rides/findrides/?off=0&cnt=20&ist=false"), function(res){ 
     if(res.status == 200){ 
     var data = JSON.parse(res._response).data; 
     console.log("API data", data); 
     for(i = 0; i < data.length; i++){ 
      Realm.write(() => { 
      Realm.create('Rides',{ 
       idx: data[i].idx, 
       nm: data[i].nm, 
       sdt: data[i].sdt, 
       edt: data[i].edt, 
       flt: data[i].flt, 
       fln: data[i].fln, 
       tlt: data[i].tlt, 
       tln: data[i].tln, 
       uid: data[i].uid, 
       ist: data[i].ist, 
       isg: data[i].isg, 
       ec: data[i].ec, 
       // kms: data[i].kms, 
       // avs: data[i].avs, 
       // tps: data[i].tps 
      }, true); 
      self.insertLocationData(data[i]); 
      }); 
     } 
     } 
    }); 
    this.rideTiles = Array.from(Realm.objects('Rides')); 
    } 
    onRideData(event){ 
    var self = this; 
    if(event){ 
     var insertQuery = `insert into events (devId,rideId,ts,lat,lng,alt,spd,brg,hepe,vepe,ang,temp,motion,ignition,mainPower,relayState) values (
     ${event.devid} 
     ,${event.rideid} 
     ,${event.ts} 
     ,${event.lat} 
     ,${event.lng} 
     ,${event.alt} 
     ,${event.spd} 
     ,${event.brg} 
     ,${event.hepe} 
     ,${event.vepe} 
     ,${event.ang} 
     ,${event.temp} 
     ,${(event.motion ? 1 : 0)} 
     ,${(event.ignition ? 1 : 0)} 
     ,${(event.mainPower ? 1 : 0)} 
     ,${(event.relayState ? 1 : 0)})`; 
     sqlite.runQuery(insertQuery, function(result){ 

     console.log(result.rows); 
     if(result.rowsAffected === 1){ 
      self.insertedCount += 1; 
      console.log("self.insertedCount, ", self.insertedCount, "self.eventCounts, ", self.eventCounts); 
      if(self.insertedCount === self.eventCounts){ 
      //Completed Ride inserts, now compute tps avs and update in Realm 
      console.log("computing stats"); 
      var tps, avs, kms, pingData = []; 
      sqlite.runQuery("select max(spd) as tps from events where rideId="+ event.rideid, function(result){ 
       tps = result.rows.item(0).tps; 
       sqlite.runQuery(`select lat,lng,ts from events where rideId=${event.rideid} order by ts asc`, function(results){ 
       var len = results.rows.length; 
       for (let i = 0; i < len; i++) { 
        pingData.push(results.rows.item(i)); 
       } 
       console.log("pingData", pingData); 
       var stats = DistanceAndTime(pingData); 
       console.log("stats", stats); 
       kms = stats.D/1000; 
       avs = (5/18)*(stats.D/stats.T); 
       debugger 
       Realm.write(() => { 
        Realm.create('Rides', {idx:event.rideid, tps: Number(tps), kms: Number(kms), avs: Number(avs)}, true); 
       }); 
       console.log("Before", self.rideTiles); 
       self.setState({rideTiles : Array.from(Realm.objects('Rides'))}) 
       }); 
      }); 
      sqlite.runQuery('select distinct(ts) as ts from events', function(results){ 
      var uniqueDate = []; 
      var len = results.rows.length; 
      for (let i = 0; i < len; i++) { 
       console.log(uniqueDate.indexOf(new Date(results.rows.item(i).ts*1000).toDateString())); 
       if(uniqueDate.indexOf(new Date(results.rows.item(i).ts*1000).toDateString()) === -1){ 
       console.log("uniqueDate in if", uniqueDate); 
       uniqueDate.push(new Date(results.rows.item(i).ts*1000).toDateString()); 
       } 
      } 
      uniqueDate.forEach(function(value){ 
       var ts = ((new Date(value)).getTime()/1000).toFixed(0); 
       var tps, avs, kms, ang, dt = new Date(value); 
       sqlite.runQuery(`select lat,lng,ts from events where ts between ${ts} and ${ts+24*60*60} order by ts asc`, function(results){ 
       var len = results.rows.length; 
       var pingData = []; 
       for (let i = 0; i < len; i++) { 
        pingData.push(results.rows.item(i)); 
       } 
       var stats = DistanceAndTime(pingData); 
       console.log("stats", stats); 
       kms = stats.D/1000; 
       avs = (5/18)*(stats.D/stats.T); 
       console.log(`kms ${kms} avs : ${avs}`); 
       sqlite.runQuery(`select max(spd) as spd, max(ang) as ang from events where ts between ${ts} and ${ts+24*60*60}`, function(result){ 
        tps = result.rows.item(0).spd; 
        ang = result.rows.item(0).ang; 
        console.log(`tps ${tps} ang : ${ang}`); 
        Realm.write(() => { 
        Realm.create('Stats', {top:tps, avg: avs, dis: kms, ang: ang, dt: dt }, true); 
        });     
        console.log('Stats', Array.from(Realm.objects('Stats'))); 
       }); 
       }); 
      }); 
      }); 
      } 
     } 
     }); 
    } 
    } 
    insertLocationData(ride){ 
    var self = this; 
    sqlite.runQuery("select count(*) as count from events where rideId="+ ride.idx, function(result){ 
     var sqlCount = result.rows.item(0).count; 
     console.log("sqlCount : ", sqlCount, "ride ec : ", ride.ec); 
     if(sqlCount !== ride.ec){ 
     console.log("in ec eventCounts : ", self.eventCounts, "ride.ec, ", ride.ec); 
     self.eventCounts = ride.ec; 
     EE.emitEvent(EE.EVENT_TYPES.WS_REQ, AvroCodec.Encode({ 
      devid: null, 
      rideid: ride.idx, 
      count: null, 
      offset: null, 
      tsFr: ride.sdt, 
      tsTo: Math.ceil(new Date()/1000) 
      }, AvroCodec.SCHEMA.A_REQ_FILTER) 
     ); 
     } 
    }); 
    } 

    render(){ 
    return(

     <View style={{flex:1}}> 
     <View style={[styles.posAbsolute, styles.gradient]}> 
      <Gradient.MainGradient height={430}/> 
     </View> 
     <View style={{zIndex:1,flex:1}}> 
      <PRides rides={this.rideTiles} navigation={this.props.navigation} /> 
     </View> 
     </View> 
    ) 
    } 
} 

const styles = { 
    img: { 
    height: 24, 
    width: 24, 
    }, 
    gradient:{ 
    left:0, 
    right:0 
    }, 
    header:{ 
    paddingTop:10, 
    paddingLeft:20, 
    paddingRight:20 
    }, 

    posAbsolute: { 
    position: 'absolute', 
    }, 
} 

回答

0

在你的渲染代碼,rideTiles未設置爲state

<View style={{zIndex:1,flex:1}}> 
    <PRides rides={this.rideTiles} navigation={this.props.navigation} /> 
</View> 

要通過setState功能進行更新,this.rideTiles必須this.state.rideTiles,這應該在你的構造,因爲這被初始化:

this.state = { 
    rideTiles: [] 
};