The ReactNative ListView is a little weird when it comes to updating data.
I have an array of objects (name: Item) that have 3 properties:
- id (int)
- name (string)
- enabled (bool)
An array of items is displayed in the ListView. Each line shows the name of the element and a checkmark indicating the enabled state (red to true, gray to false). In my example, the simple string "true" / "false" is simplified.
Each row is embedded in TouchableOpacity using the onPress-EventHandler, which toggles the allowed state of the presented element.
Unfortunately, ListView will not update the row.
When debugging the rowHasChanged-Event, it turns out that the rowHasChanged-Event can never determine the changed state, since both rows already receive a new state after switching the enabled property without any update to the user interface.
Here is my code:
Class Element: Item.js
export default class Item { constructor(id, name, enabled) { this._id = id; this._name = name; this._enabled = enabled; } get id() {return this._id} get name() {return this._name} set name(value) {this._name = value} get enabled() {return this._enabled} set enabled(value) {this._enabled = value} }
ListView:
'use strict'; import React, {PropTypes, Component} from 'react'; import {View,TouchableOpacity, TouchableHighlight, Text, ListView, StyleSheet} from 'react-native'; import Item from './Item'; class ItemListView extends Component { constructor(props) { super(props); this.updateListView = this.updateListView.bind(this); this.toggleItemEnabled = this.toggleItemEnabled.bind(this); this.state = { dataSource: new ListView.DataSource({ rowHasChanged: (row1, row2) => row1 != row2 }), }; } componentDidMount() { this.updateListView(this.props.items) } componentWillReceiveProps(nextProps) { this.updateListView(nextProps.items) } updateListView(items) { this.setState({ dataSource: this.state.dataSource.cloneWithRows( items.slice()
How to fix this behavior so that ListView is updated when row data changes?