Ryan
Ryan

Reputation: 544

Component not updating after data changes in React Native

Let me preface this by saying I'm new to React and React Native so I might be making some obvious mistakes.

I'm using a React Native module (https://github.com/rt2zz/react-native-contacts) to access my phone's contact list then I'm trying to display those contacts in a Listview. However, after running my app in an emulator (Genymotion) it doesn't update the Listview based on the data changes I made to the contacts array.

Here's my index.android.js:

import React, {AppRegistry, Component, StyleSheet, TouchableOpacity, Text, 

View, ListView} from 'react-native';

var l_mContacts = require('react-native-contacts');

var l_cAllContacts = [ ];

var newPerson = {
  familyName: "Nietzsche",
  givenName: "Friedrich",
  emailAddresses: [{
    label: "work",
    email: "[email protected]",
    number: "123456789"
  }]
}; //sample person

  l_mContacts.addContact(newPerson, (err, contacts) => { 
  if(err && err.type === 'permissionDenied'){
    alert("error");
  } else {
  }

  }) 



  l_mContacts.getAll((err, contacts) => {
    if(err && err.type === 'permissionDenied'){
      alert("error");
    } else {
      l_cAllContacts = contacts; //data changes here
      alert(contacts); //I can successfully see the sample contact I added here
    }
  });

class ReactNativeTest extends Component {
  constructor(props){
    super(props)
    var ds = new ListView.DataSource({
      rowHasChanged: (r1, r2) => r1 !== r2,
      enableEmptySections: true
    })
    this.state = {
      contactDataSource: ds.cloneWithRows(l_cAllContacts)
    }
  }
  render() {
    return (
      <View>
          <ListView 
          dataSource={this.state.contactDataSource}
          renderRow={(contact) => {return this._renderContactRow(contact)}}
          />
      </View>
    );
  }

  _renderContactRow(contact){
    return (
      <View>
        <Text>{contact ? contact.givenName : "none"}</Text>
      </View>
    )
  }
}

AppRegistry.registerComponent('ReactNativeTest', () => ReactNativeTest);

Any ideas what I'm doing wrong? When I alert the "contacts" variable inside the "l_mContacts.getAll" function I see the results I expect but it doesn't update the component. I appreciate any help, thanks.

Upvotes: 3

Views: 4093

Answers (1)

Daniel Schmidt
Daniel Schmidt

Reputation: 11921

The problem is you kind of ignore react in your doing. Let me just quickly explain how a component in React works from a programmers perspective: It renders one time in the beginning and if either its state or its props change a re-render is caused.

What you do is getting the information to display on file load. This may work once, but you have no possibility to get any information that changed or is somehow wrapped in a callback. What you can do is to run the getAll method in the constructor and use a setState within the callback to set the contactDataSource state again.

Upvotes: 3

Related Questions