Reputation: 544
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
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