React-Native. Can only update a mounted or mounting component - javascript

import React, {Component} from 'react'
import {
Image,
AppRegistry,
StyleSheet,
Text,
View,
TextInput,
TouchableOpacity,
ListView,
TouchableHighlight
} from 'react-native'
import ViewContainer from '../../components/ViewContainer';
import StatusbarBackground from "../../components/StatusbarBackground";
import firebase from 'firebase';
export default class Comments extends Component {
constructor(props) {
super(props)
const ds = new ListView.DataSource({rowHasChanged: (r1, r2) => r1 !== r2});
this.state = {
dataSource: ds.cloneWithRows(['row 1', 'row 2']),
comment: '',
post: '',
}
this.componentDidMount();
this.componentDidMount = this.componentDidMount(this);
this.listenForItems = this.listenForItems.bind(this);
this.renderItem = this.renderItem.bind(this);
this._comment = this._comment.bind(this);
}
componentDidMount() {
var commentsRef = firebase.database().ref('/comments')
this.listenForItems(commentsRef);
}
listenForItems(commentsRef) {
var commentsRef = firebase.database().ref('/comments')
commentsRef.on('value', snap => {
var items = [];
snap.forEach((child) => {
if(child.val().post == this.state.post){
items.push({
post: child.val().post,
email: child.val().email,
comment: child.val().comment,
uid: child.key
});
}
});
var temp = []
var len = items.length;
for (var i = (len - 1); i >= 0; i--) {
temp.push(items[i]);
}
items = temp;
this.setState({
dataSource: this.state.dataSource.cloneWithRows(items)
});
});
}
_comment(post) {
var commentRef = firebase.database().ref('/comments');
var curr = firebase.auth().currentUser.email;
var newComment = commentRef.push();
newComment.set({
'post': post,
'email': curr,
'comment': this.state.comment,
});
}
renderItem(item) {
return (
<TouchableHighlight>
<View style={styles.post}>
<Text style={styles.email}>{item.email}{' said:'}</Text>
<Text style={styles.text}>{item.comment}</Text>
<Text style={styles.line}></Text>
</View>
</TouchableHighlight>
)
}
render() {
this.state.post = this.props.post
return (
<ViewContainer>
<StatusbarBackground />
<Image style={styles.title}
source={require('../../images/comment.png')}
/>
<TextInput
style={styles.textinput}
multiline={true}
placeholder = "Write something..."
onChangeText={(comment) => this.setState({comment: comment})}
value={this.state.comment}
placeholderTextColor = 'black'
underlineColorAndroid = 'white'
autoCorrect = {false}
/>
<View style={styles.comment}>
<TouchableOpacity onPress={() => {this._comment(this.props.post)}}>
<Text>Publish</Text>
</TouchableOpacity>
</View>
<View style={styles.container}>
<ListView
dataSource={this.state.dataSource}
renderRow={this.renderItem} />
</View>
</ViewContainer>
)
}
}
I'm making a social app with posts, likes and comments. When I want to see the comments of a post I'm rendering a list view with all the comments. The first try it works but if I want to see the comments of other post I get this error.
I think I have to use componentWillUnmount() but idk what code I have to put there. Any ideias? Thanks!

Remove this.componentDidMount() from your constructor, and remove the line where you bind it. It is called automatically in the React component lifecycle, which is available because you extend Component.
You should also have the componentWillUnmount function that should call something like:
this.commentsRef.off(...)
In order to remove the listener. In order to do that correctly, move the commentsRef callback to its own class function (call it onCommentsRefValue or something), and then you can do this.commentsRef.on('value', this.onCommentsRefValue ) and subsequently in componentWillUnmount you can call this.commentsRef.off('value', this.onCommentsRefValue )

Related

How to render data in ScrollView React Native (expo cli) from firebase realtime database?

I'm working on a ToDo app that is connected to the Firebase real-time database. Everything works fine. I can also store data in the Firebase database, but the problem is that I cannot get any data from the database. I want to render data in ScrollView so that the data can be displayed in ScrollView when I open my app.
Main.js
import React, { Component } from 'react';
import {
StyleSheet,
Text,
View,
TextInput,
ScrollView,
TouchableOpacity
} from 'react-native';
import Note from './Note';
import firebase from './firebase';
export default class Main extends React.Component {
constructor(props) {
super(props);
this.state = {
noteArray: [],
noteText: ''
}
}
render() {
let notes = () => {
firebase.database().ref(`todos`).on('value', function (snapshot) {
return <Note key={snapshot.val().key} keyval={snapshot.val().key} val={snapshot.val().note}
deleteMethod={() => this.deleteNote(key)}
/>
});
}
return (
<View style={styles.container}>
<View style={styles.header}>
<Text style={styles.headerText}>Todo</Text>
</View>
<ScrollView style={styles.scrollContainer}>
{notes}
</ScrollView>
<View style={styles.footer}>
<TextInput
style={styles.textInput}
onChangeText={(noteText) => this.setState({ noteText })}
value={this.state.noteText}
placeholder='Enter Task'
placeholderTextColor='white'
underlineColorAndroid='transparent'>
</TextInput>
</View>
<TouchableOpacity onPress={this.adTask.bind(this)} style={styles.addButton}>
<Text style={styles.addButtonText}>Add</Text>
</TouchableOpacity>
</View>
);
}
adTask() {
if (this.state.noteText) {
var date = new Date();
var database = firebase.database().ref('todos');
var key = database.push().key;
var todo = {
'date': date.getDay() +
'/' + (date.getMonth() + 1) +
'/' + date.getFullYear(),
'note': this.state.noteText,
key: key
}
database.child(key).set(todo);
this.setState({ noteArray: this.state.noteArray });
this.setState({ noteText: this.state.noteText });
this.setState({
noteText: this.state.noteText = ""
})
}
}
note.js
import React from 'react';
import { StyleSheet, Text, View, TouchableOpacity } from 'react-native';
import { AntDesign } from '#expo/vector-icons';
export default class Main extends React.Component {
render() {
return (
<View key={this.props.keyval} style={styles.note}>
<Text style={styles.noteText}>{this.props.val.note}</Text>
<Text style={styles.noteDate}>{this.props.val.date}</Text>
<TouchableOpacity onPress={this.props.deleteMethod} style={styles.noteDelete}>
<Text style={styles.noteDeleteText}><AntDesign name="delete" size={24} color="black" /></Text>
</TouchableOpacity>
</View>
);
}
}
You have delcared the noteArray state variable but you are not using it at all. Ideally you should setup a data change listener to realtime database and should update your local state when the data changes. You can setup a listener function and call it inside your Main.js file componentDidMount lifecycle method.
Inside this function, you can update your local state noteArray with the value received from the realtime database. You can then map over the noteArray to display your notes in your application with the help of a scrollview. I would personally suggest you to use the FlatList implementation of the react native in this use case, as this note array can grow over time. This will help you from the performace issues that you might face in the case of a long list and scrollview.
Main.js
import React, { Component } from 'react';
import {
StyleSheet,
Text,
View,
TextInput,
ScrollView,
TouchableOpacity,
FlatList
} from 'react-native';
import Note from './Note';
import firebase from './firebase';
export default class Main extends React.Component {
constructor(props) {
super(props);
this.state = {
noteArray: [],
noteText: ''
}
}
componentDidMount() {
this.listenForNotes()
}
listenForNotes() {
firebase.database().ref(`todos`).on('value', function (snapshot) {
const notes = [];
snapshot.forEach(child => {
notes.push({
note: child.val().name,
date: child.val().date,
key: child.key
});
});
this.setState({
noteArray: notes
});
});
}
adTask() {
if (this.state.noteText) {
var date = new Date();
var database = firebase.database().ref('todos');
var key = database.push().key;
var todo = {
'date': date.getDay() +
'/' + (date.getMonth() + 1) +
'/' + date.getFullYear(),
'note': this.state.noteText,
key: key
}
database.child(key).set(todo);
this.setState({ noteText: "" });
}
}
deleteNote(key) {
// your delete note function
}
render() {
return (
<View style={styles.container}>
<View style={styles.header}>
<Text style={styles.headerText}>Todo</Text>
</View>
<FlatList
data={noteArray}
renderItem={({ item, index }) => {
return (
<Note
key={item.key}
note={item.note}
date={item.date}
deleteMethod={() => this.deleteNote(key)}
/>
);
}}
key={(item) => `${item.key}`}
/>
<View style={styles.footer}>
<TextInput
style={styles.textInput}
onChangeText={(noteText) => this.setState({ noteText })}
value={this.state.noteText}
placeholder='Enter Task'
placeholderTextColor='white'
underlineColorAndroid='transparent'>
</TextInput>
</View>
<TouchableOpacity onPress={this.adTask.bind(this)} style={styles.addButton}>
<Text style={styles.addButtonText}>Add</Text>
</TouchableOpacity>
</View>
);
}
}
You should also make some changes in the Note.js file to display the passed props.
Note.js
import React from 'react';
import { StyleSheet, Text, View, TouchableOpacity } from 'react-native';
import { AntDesign } from '#expo/vector-icons';
export default class Note extends React.Component {
constructor(props) {
super(props);
}
render() {
const { note, date, key, deleteMethod } = this.props;
return (
<View key={key} style={styles.note}>
<Text style={styles.noteText}>{note}</Text>
<Text style={styles.noteDate}>{date}</Text>
<TouchableOpacity onPress={deleteMethod} style={styles.noteDelete}>
<Text style={styles.noteDeleteText}><AntDesign name="delete" size={24} color="black" /></Text>
</TouchableOpacity>
</View>
);
}
}

onSubmitEditing never fires?

Really simple question, why isn't onSubmitEditing firing when I hit 'Search' on the virtual keyboard?
Currently there are no errors thrown and the console.log in onSearch() never fires.
I'm using the EXPO SDK v.29.
import React from 'react';
import { StyleSheet, Text, View, TextInput, ScrollView, Image } from 'react-native';
import { WebBrowser } from 'expo';
import Icon from 'react-native-vector-icons/Ionicons';
import Styles from 'app/constants/Styles';
import Vars from 'app/constants/Vars';
import Menu from 'app/components/Menu';
import MiniMap from 'app/components/MiniMap';
import NewsList from 'app/components/NewsList';
import {get, post} from 'app/helpers/api';
export default class HomeScreen extends React.Component {
static navigationOptions = ({ navigation }) => {
return {
headerTitle: (<Image style={{width: 132, height: 30}} source={require('./../../assets/images/header_image.png')}/>)
};
};
constructor(props) {
super(props);
this.state = {
menu: [],
loadingMenu: true,
searchString: '',
};
}
onMenuPress = (item) => {
let next;
let route = item.page_type.slice(4);
if(route == "PageExternal") {
WebBrowser.openBrowserAsync(item.page.url);
} else {
data = item.page;
if(item.children.length > 0) {
route = 'Menu';
data = item.children;
}
this.props.navigation.navigate(route, {
data: data,
title: item.title
});
}
}
onSearch = (e) => {
console.log('onSearch', e);
//WebBrowser.openBrowserAsync('https://www.1177.se/Halland/Sok/?q=Diabetes&submitted=true');
}
async componentDidMount() {
console.log('Eat my shorrs');
menuitems = await get('content/menu');
this.setState({
menu: menuitems,
loadingMenu: false,
})
//this._getMenu();
}
render() {
return (
<ScrollView style={Styles.whiteBackground}>
<View style={[Styles.blueBackground, Styles.topPadding, Styles.horizontalPadding]}>
<View style={[Styles.searchBox, Styles.bottomMargin]}>
<View style={Styles.searchField}>
<TextInput
style = {Styles.searchInput}
placeholder = "Sök sjukdom/behandling"
onSubmitEditing = {(e) => (this.onSearch(e))}
underlineColorAndroid = "transparent"
returnKeyLabel = "Sök på 1177"
returnKeyType = "search"
/>
<Icon style = {Styles.searchIcon} name = "ios-search" size={18}/>
</View>
<Text style={[Styles.searchLabel]}>Söksvaren kommer från 1177.se</Text>
</View>
<Menu
data={this.state.menu}
loading={this.state.loadingMenu}
style={Styles.topPadding}
onItemPress={this.onMenuPress}
/>
</View>
<Text style={[Styles.h1, Styles.blackText, Styles.horizontalPadding]}>Hitta till oss</Text>
<MiniMap navigation={this.props.navigation}></MiniMap>
<Text style={[Styles.h1, Styles.blackText, Styles.horizontalPadding]}>Nyheter</Text>
<NewsList navigation={this.props.navigation}></NewsList>
</ScrollView>
);
}
}
<TextInput
onSubmitEditing = {(event) => (this.onSearch(event.nativeEvent.text))}
multiline={false}
/>
It does not work when multiline={true} is specified, perhaps your styles has that. See Documentation
You will find your text with event.nativeEvent.text
Try changing
onSubmitEditing = {(e) => (this.onSearch(e))}
to
onSubmitEditing = {this.onSearch}
Then keep
onSubmitEditing = {(e) => this.onSearch(e)}
like this and try by changing the function like below
function onSearch(e) {
console.log('onSearch', e);
//WebBrowser.openBrowserAsync('https://www.1177.se/Halland/Sok/?q=Diabetes&submitted=true');
}
Hope this will work
Check this out
https://snack.expo.io/#raajnadar/submit-text-input
Render method
render() {
return (
<View style={styles.container}>
<TextInput
placeholder="Sök sjukdom/behandling"
onSubmitEditing={this.onSearch}
underlineColorAndroid="transparent"
returnKeyLabel="Sök på 1177"
returnKeyType="search"
style={{ width: '100%', textAlign: 'center' }}
/>
</View>
);
}
On submit function
onSearch() {
console.log('onSearch')
}

React Native - Modal with Flatlist items

I'm making a modal that will popup when the user clicks a flatlist button or items, and there the user will see the details about the item he/she clicks. Basically, I want to pass the items of flatlist to modal.
I'm actually done with the popup of the modal, now I have to show the details like menu description and menu price. I've found a post here in stackoverflow and I follow everything in there but I am having an error regarding with an " id ", and I can't figure out how to fix it.
Here is my code
Details.js
import React, {Component} from 'react';
import {Text, TouchableHighlight, View,
StyleSheet, Platform, FlatList, AppRegistry,
TouchableOpacity, RefreshControl, Dimensions, Modal, TextInput, TouchableWithoutFeedback, Keyboard
} from 'react-native';
import AddModal from '../Modal/AddModal';
var screen = Dimensions.get('window');
const DismissKeyboard = ({ children }) => (
<TouchableWithoutFeedback onPress = {() => Keyboard.dismiss()}>
{children}
</TouchableWithoutFeedback>
);
export default class Details extends Component {
static navigationOptions = {
title: ''
};
constructor()
{
super ()
this.state = {
data: [],
showModal: false,
id: null,
}
}
fetchData = async() => {
const { params } = this.props.navigation.state;
const response_Cat = await fetch('http://192.168.254.101:3307/categories/' + params.id);
const category_Cat = await response_Cat.json();
this.setState({data: category_Cat});
};
componentDidMount() {
this.fetchData();
};
_onRefresh() {
this.setState({ refreshing: true });
this.fetchData().then(() => {
this.setState({ refreshing: false })
});
};
_onPressItem(id) {
this.setState({
modalVisible: true,
id: id
});
}
_renderItem = ({item}) => {
return (
<TouchableHighlight
id = { item.menu_desc }
onPress = { this._onPressItem(item.menu_desc) }
>
<View>
<Text>{ this.state.id }</Text>
</View>
</TouchableHighlight>
)
};
render() {
const { params } = this.props.navigation.state;
return (
<View style = { styles.container }>
<AddModal
modalVisible = { this.state.modalVisible }
setModalVisible = { (vis) => { this.setModalVisible(vis) }}
id = { this.state.id }
/>
<FlatList
data = { this.state.data }
renderItem = { this._renderItem }
keyExtractor={(item, index) => index}
/*refreshControl = {
<RefreshControl
refreshing = { this.state.refreshing }
onRefresh = { this._onRefresh.bind(this) }
/>
}*/
/>
</View>
);
}
}
const styles = StyleSheet.create({
...
})
//AppRegistry.registerComponent('Details', () => Details);
AddModal.js
import React, {Component} from 'react';
import {Text, TouchableHighlight, View,
StyleSheet, Platform, FlatList, AppRegistry,
TouchableOpacity, RefreshControl, Dimensions, TextInput, Modal
} from 'react-native';
export default class AddModal extends Component {
constructor(props) {
super(props);
this.state = {
showModal: false,
id: null
};
}
componentWillReceiveProps(nextProps) {
this.setState({
showModal: nextProps.showModal,
id: nextProps.id,
})
}
render() {
return (
<Modal
animationType="slide"
transparent={ true }
visible={ this.state.modalVisible }
onRequestClose={() => { this.props.setModalVisible(false) }}>
<View>
<View>
<Text>{ this.state.id }</Text>
<TouchableHighlight
onPress = {() => { this.props.setModalVisible(false) }}
>
<Text>Hide Modal</Text>
</TouchableHighlight>
</View>
</View>
</Modal>
)
}
}
Just wanted to pointout an issue in your code (not related to 'id' error, id error already answer by digit). In the renderItem function, you are calling onPress = { this._onPressItem(item.menu_desc) }, it should be changed to
onPress = { () => this._onPressItem(item.menu_desc) }
I guess, you will call the onPressItem when user click on list item.
EDIT:
I have made a couple of changes to make your code working. Here are the changes.
In your AppModal.js, you are setting modal visibility in showModal: nextProps.showModal , but in the <Modal ...> you have set visible
= { this.state.modalVisible }. Also in Details.js you have written <AddModal modalVisible ...>.
First I changed showModal to modalVisible in Details.js and in AppModal.js.
Details.js
constructor()
{
super ()
this.state = {
data: [],
modalVisible: false,
id: null,
}
}
Then I changed _onPressItem(id) to _onPressItem = (id)
Made changes in renderItem as
<TouchableHighlight
id = { item.enName }
onPress = { () => this._onPressItem(item.enName) }
>
in render function I have set modal visibility as
<AddModal
...
setModalVisible = { (vis) => { this.setState({
modalVisible: vis
})
}}
...
/>
AppModal.js
Changed showModal to modalVisible
constructor(props) {
super(props);
this.state = {
modalVisible: props.modalVisible,
d: null
};
}
componentWillReceiveProps(nextProps) {
this.setState({
modalVisible: nextProps.modalVisible,
id: nextProps.id,
})
}
In the constructor, I have added modalVisible: props.modalVisible.
Hope this will help!
I guess item.menu_desc is an id of each item so it must be {item.menu_desc} not {id}. Change it like below
_renderItem = ({item}) => {
return (
<TouchableHighlight
id = { item.menu_desc }
onPress = { this._onPressItem(item.menu_desc) }
>
<View>
<Text>{ item.menu_desc }</Text>
</View>
</TouchableHighlight>
)
};

React-native constructor and componentWillMount scope issue

I want to display all items in my array monthDays with map.
The problem is that i need to execute some logic in a componetWillMount to creact the array by pushing items to it in a loop.
The alterations that i made in the componetWillMount are not afecting the array in the constructor.
Sorry if im not being clear, my english is not that good
Here is the code:
import React, { Component } from 'react';
import {
Platform,
StyleSheet,
Text,
View
} from 'react-native';
export default class Calendar extends Component {
constructor(props){
super(props);
this.state = {text: ''};
this.monthDays = ['I want to put this array'];
}
componentWillMount(){
let monthDays = ['in this scope'];
let defineDays = Number(this.props.days);
let daysCount = 1;
let x = 0;
while (monthDays.length < defineDays) {
monthDays.push(daysCount);
daysCount++;
this.setState({ text : monthDays[x]});
x++;
}
}
render() {
return (
<View style={styles.container}>
{this.monthDays.map(( teste, key ) => (
<View key = { key }>
<Text>{ teste }</Text>
</View>
))}
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#F5FCFF',
}
});
Ps: defineDays only received a prop with the number of days the month have
You can try this:
componentWillMount() {
let monthDays = ['in this scope'];
let defineDays = Number(this.props.days);
let daysCount = 1;
let x = 0;
while (monthDays.length < defineDays) {
monthDays.push(daysCount);
daysCount++;
this.setState({ text: monthDays[x] });
x++;
}
// Assign the new values to your current array
this.monthDays = monthDays;
}
If you are going to receive props new props over the time you need to do the same thing in componentWillReceiveProps if you want to maintain this.monthDays updated.
Try this:
export default class Calendar extends React.Component{
constructor(){
super();
this.mapFunction = this.mapFunction.bind(this);
}
function mapFunction() {
var arr = []
for(var dayscount=0; dayscount < this.props.days; dayscount++){
arr.push(dayscount);
}
return arr.map((test, key) => {
return (
<View key = { key }>
<Text>{ test }</Text>
</View>
)
})
}
render(){
return(
<View>
{ this.mapFunction }
</View>
)
}
}
Make sure you are setting this.props.days correctly and it's value is an integer.

ListView is not re-rendering after dataSource has been updated

I am trying to implement a todo app in react-native with features like addTodo, removeTodo, markCompleted todos. After adding todos, when I press on markComplete text, the listView is not re-rendering, if I reload the app it displays expected results. I am using Firebase database to fetch my todos from.
Basically, I am updating a property in my listView datasource when I click on markComplete. Everything is working fine expect the re-rendering of listView whenever I press markComplete or Completed buttons on UI. I have tried a few solutions suggested in related question, I couldnt get it working.
To be more specific: please look at code below comment // When a todo is changed. I am updating my datasource in those lines of code when I changes something in items array.
Below is my code and snapshot of app UI.
import React, { Component } from 'react';
import {
AppRegistry,
StyleSheet,
ListView,
Text,
View,
TouchableHighlight,
TextInput
} from 'react-native';
var Firebase = require('firebase');
class todoApp extends Component{
constructor(props) {
super(props);
var myFirebaseRef = new Firebase('[![enter image description here][1]][1]database URL');
this.itemsRef = myFirebaseRef.child('items');
this.state = {
newTodo: '',
completed: false,
todoSource: new ListView.DataSource({rowHasChanged: (row1, row2) => row1 !== row2})
};
this.handleKey = null;
this.items = [];
} // End of Constructor
componentDidMount() {
// When a todo is added
this.itemsRef.on('child_added', (dataSnapshot) => {
this.items.push({
id: dataSnapshot.key(),
text: dataSnapshot.child("todo").val(),
completedTodo: dataSnapshot.child("completedTodo").val()
});
this.setState({
todoSource: this.state.todoSource.cloneWithRows(this.items)
});
});
// When a todo is removed
this.itemsRef.on('child_removed', (dataSnapshot) => {
this.items = this.items.filter((x) => x.id !== dataSnapshot.key());
this.setState({
todoSource: this.state.todoSource.cloneWithRows(this.items)
});
});
// When a todo is changed
this.itemsRef.on('child_changed', (dataSnapshot) => {
this.items.forEach(function (value) {
if(value["id"] == this.handleKey){
this.items["value"]["completedTodo"]= dataSnapshot.child("completedTodo").val()
}
});
this.setState({
todoSource: this.state.todoSource.cloneWithRows(this.items)
});
});
}
addTodo() {
if (this.state.newTodo !== '') {
this.itemsRef.push({
todo: this.state.newTodo,
completedTodo: this.state.completed,
});
this.setState({
newTodo : ''
});
}
console.log(this.items);
}
removeTodo(rowData) {
this.itemsRef.child(rowData.id).remove();
}
handleCompleted(rowData){
this.handleKey = rowData.id;
if(rowData.completedTodo){
this.itemsRef.child(rowData.id).update({
completedTodo: false
})
}
if(rowData.completedTodo == false){
this.itemsRef.child(rowData.id).update({
completedTodo: true
})
}
}
renderRow(rowData) {
return (
<View>
<View style={styles.row}>
<TouchableHighlight
underlayColor='#dddddd'
onPress={() => this.removeTodo(rowData)}>
<Text style={styles.todoText}>{rowData.text}</Text>
</TouchableHighlight>
<TouchableHighlight underlayColor='#dddddd' onPress={() => this.handleCompleted(rowData)}>
{rowData.completedTodo? <Text style={styles.todoText}>Completed</Text>:<Text style={styles.todoText}>MarkCompleted</Text>}
</TouchableHighlight>
</View>
<View style={styles.separator} />
</View>
);
}
render() {
return (
<View style={styles.appContainer}>
<View style={styles.titleView}>
<Text style={styles.titleText}>
My Todos
</Text>
</View>
<View style={styles.inputcontainer}>
<TextInput style={styles.input} onChangeText={(text) => this.setState({newTodo: text})} value={this.state.newTodo}/>
<TouchableHighlight
style={styles.button}
onPress={() => this.addTodo()}
underlayColor='#dddddd'>
<Text style={styles.btnText}>Add!</Text>
</TouchableHighlight>
</View>
<ListView
dataSource={this.state.todoSource}
renderRow={this.renderRow.bind(this)} />
</View>
);
}
} // Main Class End
Make sure to create new objects instead of updating the properties of existing objects.
If you want to update listView, create new objects instead of updating
the properties of existing objects.
The below code resolved a similar issue on Github.
let newArray = oldArray.slice();
newArray[indexToUpdate] = {
...oldArray[indexToUpdate],
field: newValue,
};
let newDataSource = oldDataSource.cloneWithRows(newArray);
For more detailed explanation, This answer might help you.

Categories

Resources