setState不更改UI数据

时间:2017-06-02 01:01:13

标签: reactjs react-native

我有一个具有componentWillMount的react组件,并使用setState方法更新状态。我正在使用一个对象数组更新状态变量rideTiles,尽管我没有获取用于渲染的ant数据。我通过返回默认值shouldComponentUpdate()尝试了true,但仍未使用更新的值呈现组件。我无法确定出了什么问题?

这是我的代码

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',
  },
}

1 个答案:

答案 0 :(得分: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: []
};