反应本机 ListView 数据源不更新
Posted
技术标签:
【中文标题】反应本机 ListView 数据源不更新【英文标题】:react native ListView datasource not updating 【发布时间】:2017-07-27 07:08:42 【问题描述】:我正在尝试更新数据源,并且我检查了以下网址
https://github.com/facebook/react-native/issues/4104 https://github.com/mobxjs/mobx/issues/569
我厌倦了创建一个新数组然后更新它,但我不确定如何更新数据源。
在更改复选框时,我正在更新对象并将其分配给数据源,但复选框未更新。
下面是我尝试过的代码。
构造函数
constructor()
super();
const ds = new ListView.DataSource(rowHasChanged: (r1, r2) => r1 !== r2);
this.state =
modalVisible: false,
todoText:'',
todoListArray:[],
dataSource: ds
;
列表视图
<ListView
dataSource=this.state.dataSource
renderRow=this.generateRow.bind(this)
/>
generateRow=(rowData, sectionID, rowID, highlightRow) =>
return (
<View style=styles.listItem>
<CheckBox
label=''
checked=rowData.isCompleted
onChange=() => this.changeisCompleted(this,rowID)
/>
<Text style=styles.listItemText>rowData.text</Text>
</View>
);
/*When Checkbox is clicked*/
changeisCompleted=(rowData,rowId)=>
var newDs = [];
newDs = this.state.todoListArray.slice();
newDs[rowId].isCompleted =!newDs[rowId].isCompleted;
alert(JSON.stringify(newDs));
this.setState(
dataSource: this.state.dataSource.cloneWithRows(newDs)
)
/*adding new item to listView*/
addTodo = () =>
var todoObj=
"text":this.state.todoText,
"isCompleted":false
this.state.todoListArray.push(todoObj);
this.closeModal();
this.setState(todoText: '');
this.setState(
dataSource: this.state.dataSource.cloneWithRows(this.state.todoListArray)
)
添加整个文件:
/**
* Sample React Native App
* https://github.com/facebook/react-native
* @flow
*/
import React, Component from 'react';
import
AppRegistry,
StyleSheet,
Text,
View,
Toolbarandroid,
Modal,
Button,
TextInput,
Image,
ListView,
TouchableHighlight
from 'react-native';
import CheckBox from 'react-native-checkbox';
/*import AddToDoModal from './src/components/AddTodoModal.js';*/
export default class FirstReactNativeApp extends Component
constructor()
super();
const ds = new ListView.DataSource(rowHasChanged: (row1, row2) => row1 !== row2);
this.state =
modalVisible: false,
todoText:'',
todoListArray:[],
dataSource: ds,
;
componentDidMount = () => function()
openModal = () =>
this.setState(modalVisible: true);
closeModal = () =>
this.setState(modalVisible: false);
setModalVisible=(visible) =>
this.setState(modalVisible: visible);
changeisCompleted=(rowData,rowId)=>
var newDs = [];
newDs = this.state.todoListArray.slice();
newDs[rowId].isCompleted =!newDs[rowId].isCompleted;
newDs[rowId].text ="Changed";
alert(JSON.stringify(newDs));
//this.state.todoListArray=newDs;
//alert("listArray=="+JSON.stringify(this.state.todoListArray))
this.setState(
todoListArray:newDs,
dataSource: this.state.dataSource.cloneWithRows(newDs)
)
addTodo = () =>
var todoObj=
"text":this.state.todoText,
"isCompleted":false
this.state.todoListArray.push(todoObj);
this.closeModal();
this.setState(todoText: '');
this.setState(
dataSource: this.state.dataSource.cloneWithRows(this.state.todoListArray)
)
generateRow=(rowData, sectionID, rowID, highlightRow) =>
return (
<View style=styles.listItem>
<CheckBox
label=''
checked=rowData.isCompleted
onChange=() => this.changeisCompleted(this,rowID)
/>
<Text style=styles.listItemText>rowData.text</Text>
</View>
);
render()
return (
<View>
<ToolbarAndroid
style=styles.toolbar
title="ToDo List"
actions=[title: 'Add', icon: require('./img/add.png'), show: 'always']
onActionSelected=this.openModal
/>
<ListView
dataSource=this.state.dataSource
renderRow=this.generateRow.bind(this)
/>
<Modal
animationType="none"
transparent=false
visible=this.state.modalVisible
onRequestClose=() => alert("Modal has been closed.") >
<View style=styles.container>
<View style=styles.modalContent>
/*this is icon button*/
<TouchableHighlight style=justifyContent:'flex-end',flexDirection:'row' onPress=this.closeModal>
<Image
style=styles.closeButton
source=require('./img/close.png')
/>
</TouchableHighlight>
<Text style=textAlign:'center',marginBottom:30>Add New ToDo</Text>
<TextInput
style=height: 40, borderColor: 'gray', borderWidth: 1,marginBottom:10
placeholder='Enter ToDo'
onChangeText=(todoText) => this.setState(todoText)
value=this.state.todoText
/>
<Button
onPress=()=> this.addTodo()
title='Add ToDo'
color='#1e90ff'/>
</View>
</View>
</Modal>
</View>
);
const styles = StyleSheet.create(
container:
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#000000',
opacity:0.8
,
welcome:
fontSize: 20,
textAlign: 'center',
margin: 10,
,
instructions:
textAlign: 'center',
color: '#333333',
marginBottom: 5,
,
toolbar:
height:55,
backgroundColor: '#1e90ff',
,
modal:
height:50,
marginVertical:22,
,
modalContent:
backgroundColor: '#ffffff',
height:300,
width:300,
borderRadius:3,
paddingVertical:10,
paddingHorizontal:20,
,
closeButton:
height:30,
width:30,
,
listItem:
backgroundColor: '#ffffff',
paddingLeft:10,
height:50,
borderBottomWidth:1,
borderColor: '#000000',
flex:1,
flexDirection:'row',
alignItems:'center',
,
listItemText:
fontSize:20,
);
AppRegistry.registerComponent('FirstReactNativeApp', () => FirstReactNativeApp);
【问题讨论】:
您好样品可能会解决您的问题尝试一下hellokoding.com/todo-app-with-react-native-realm ***.com/questions/31738671/… 我已经尝试了这两个链接,请检查更新的代码并提出其中的任何错误。 【参考方案1】:所以经过大量阅读和更改后,列表视图现在正在更新。 根据this发帖
将 ds 声明更改为:
this.ds = new ListView.DataSource(rowHasChanged: (row1, row2) => row1 !== row2);
所以改变了我的 changeisComplete 方法
changeisCompleted=(rowData,rowId)=>
var newDs = [];
newDs = this.state.todoListArray.slice();
newDs[rowId].isCompleted =!newDs[rowId].isCompleted;
this.setState(
dataSource: this.ds.cloneWithRows(this.state.todoListArray),
todoListArray:newDs
)
我不确定这是否是正确的方法,但无论如何它有效,现在复选框正在更改
谢谢
【讨论】:
【参考方案2】:你有两个问题。首先,您将数据源设置为克隆的结果。只需使用 this.state.dataSource:
dataSource=this.state.dataSource.cloneWithRows(this.state.todoListArray)
因为您正在设置 DS 结果而不是链接数据源。此外,您不需要状态中的双数据(数组和数据源)。
第二个也是最重要的,你实际上并没有设置状态。只有在构造函数中,您才能像这样设置它:this.state。
之后只能这样设置:
this.setState(dataSource: this.state.dataSource.cloneWithRows(updatedArray));
【讨论】:
更新了我的代码。请检查 addToDo 方法将新对象添加到列表视图中。但是 changeisCompleted 方法什么也不做。以上是关于反应本机 ListView 数据源不更新的主要内容,如果未能解决你的问题,请参考以下文章