React Native:在Render中调用的函数,在循环中运行

时间:2016-08-31 10:14:30

标签: javascript reactjs react-native

这是我的代码:



 "use strict";

import React, {Component, PropTypes} from 'react';
import {
  ActivityIndicator,
  ListView,
  StyleSheet,
  Text,
  TextInput,
  View,
  TouchableOpacity,
} from 'react-native';
import { Actions, ActionConst } from 'react-native-router-flux';


var SQLite = require('react-native-sqlite-storage');
var DeviceInfo = require('react-native-device-info');
import Icon from 'react-native-vector-icons/Ionicons';

var LOADING = {};
var db = SQLite.openDatabase({name : "oc.db", location: 'default'});
class Profile extends Component {

  constructor(props) {
        super(props);
        this.state = {
            users: [],
            dataSource: new ListView.DataSource({
              rowHasChanged: (row1, row2) => row1 !== row2,
            }),
        };

    }

    fetch(){
      console.log('fetching data from database');
      //////
      var query = "SELECT * FROM users";
      var params = [];
      var userlist = [];
      db.transaction((tx) => {
            tx.executeSql(query,params, (tx, results) => {
                var len = results.rows.length;
                for(var ind = 0; ind < len; ind++ ){
                  userlist[ind] = {
                    userId: results.rows.item(ind).userId,
                    userName: results.rows.item(ind).userName,
                    userMail: results.rows.item(ind).userMail,
                    active: results.rows.item(ind).active
                  };
                }
                this.setState({
                  users: userlist,
                });
              }, function(){
                console.log('Profile: Something went wrong');
              });
          });

      //////////
    }

  componentDidMount() {
    this.fetch();
  }

  activate(uid){
    console.log('Lets de-activate all accounts');
    var query = "UPDATE users SET active='no' WHERE active=?";
    var params = ['yes'];
    db.transaction((tx) => {
      tx.executeSql(query,params, (tx, results) => {
        console.log('all users should be de-active now');
        console.log('activating user ', uid);
        var query = "UPDATE users SET active='yes' WHERE userId=? LIMIT 1;";
        var params = [uid];
        db.transaction((tx) => {
          tx.executeSql(query,params, (tx, results) => {
            console.log('UserId ' , uid , ' is Active now');
            this.renderUsers();
            //Actions.bridge({type: 'reset', toGo: 'home'});
          }, function(){
            console.log('No such a user found to make active');
          });
        });
      }, function(){
        console.log('No such a user found to make active');
      });
    });
  }

  resetNav(){
    Actions.bridge({type: 'reset'});
  }

  renderUsers(){
    console.log('Rendering Users');
    //this.fetch();
    var ulist = this.state.users;
    var urow = [];
    for(let a=0; a < ulist.length; a++){
      let active = ulist[a].active === 'yes' ? '◉' : '◯';
      let usid = ulist[a].userId;
      urow.push(
        <TouchableOpacity key={a} onPress={() => { this.activate(usid); /* this.resetNav(); */ }} style={styles.uitem}>
          <Text style={styles.uText}>{ulist[a].userName} {ulist[a].userMail}</Text>
          <Text style={styles.uTextAct}>{active}</Text>
        </TouchableOpacity>
      );
    }
    return(
      <View style={styles.ulist}>{urow}</View>
    );
  }

  render() {
    return (
      <View style={styles.container}>
      <Text style={styles.pic}>
      <Icon name="ios-person" color="#00a2dd" size={180}></Icon>
      </Text>
      <Text style={styles.heading}>
        Welcome to your Profile page!{'\n'}
      </Text>
      <Text style={styles.listtitle}>Users List</Text>
      <Text style={styles.listdesc}>To switch between accounts, simply click on them.</Text>
      {this.renderUsers()}
      </View>
    );
  }
}
&#13;
&#13;
&#13;

结果显示,它正在运作。但问题是renderUsers()在循环中运行。它永远被称为。我哪里错了?有什么解决方案吗?

更新: 当我把this.fetch放到renderUsers()时,它没问题。当您选择一个用户时,它将处于活动状态,您可以看到该列表正在更新。但问题是列表在循环中更新。它一直在发生。

当我将this.fetch放到componentdidmount时,循环问题得到修复,但是当你更改活动用户时,列表没有被更新。

1 个答案:

答案 0 :(得分:1)

我找到了解决方案。在激活功能中,我从router-flux添加了Actions.refresh方法,并在componentwillreceiveprops中添加了this.setState。现在它按预期工作了。最终代码是这样的:

更改:

&#13;
&#13;
////Added this code :
componentWillReceiveProps() {
    this.fetch();
    this.setState({
      somekey: 'yes'
    });
  }

/// Added Actions.refresh({somekey: 'Yes'}); with some random props
activate(uid){
    console.log('Lets de-activate all accounts');
    var query = "UPDATE users SET active='no' WHERE active=?";
    var params = ['yes'];
    db.transaction((tx) => {
      tx.executeSql(query,params, (tx, results) => {
        console.log('all users should be de-active now');
        console.log('activating user ', uid);
        var query = "UPDATE users SET active='yes' WHERE userId=? LIMIT 1;";
        var params = [uid];
        db.transaction((tx) => {
          tx.executeSql(query,params, (tx, results) => {
            console.log('UserId ' , uid , ' is Active now');
            this.renderUsers();
            Actions.refresh({somekey: 'yes'});
            //Actions.bridge({type: 'reset', toGo: 'home'});
          }, function(){
            console.log('No such a user found to make active');
          });
        });
      }, function(){
        console.log('No such a user found to make active');
      });
    });
  }
&#13;
&#13;
&#13;

希望它能帮助那些有同样问题的人