gpt4 book ai didi

listview - react native ListView : Wrong row removed when deleting

转载 作者:行者123 更新时间:2023-12-04 04:21:11 24 4
gpt4 key购买 nike

我知道有人问过这个问题,例如hereherehere

但是,没有一个答案/评论令人满意。他们要么告诉您克隆不能解决问题的数据,要么在ListView上设置一个唯一的 key 来解决问题,但是创建一个新 key 。

当您在ListView上设置唯一键并在删除后对其进行更新时,整个 View 将再次呈现并滚动到顶部。向下滚动列表以删除项目的用户希望列表保持其位置。

这是一个人为的示例,使用我认为是克隆数据的正确方法:

var ListViewExample = React.createClass({

getInitialState() {
var ds = new ListView.DataSource({rowHasChanged: (r1, r2) => {
r1 !== r2
}});
var rows = ['row 1', 'row 2', 'row 3'];
return {
dataSource: ds.cloneWithRows(rows),
};
},

_deleteRow() {
var rows = ['row 1', 'row 3'];
this.setState({dataSource: this.state.dataSource.cloneWithRows(rows)})
},

renderRow(rowData, sectionID, rowID) {
return <TouchableOpacity onPress={this._deleteRow}
style={{height: 60, flex: 1, borderBottomWidth: 1}}>
<Text>{rowData}</Text>
</TouchableOpacity>
},

render() {
return (
<ListView
dataSource={this.state.dataSource}
renderRow={this.renderRow}
/>
);
}

});

here,您可以看到它的gif效果,其中删除了错误的行。另一种方法是,设置ListView的 key属性确实会删除正确的行,但正如我所说,这会使列表滚动到顶部。

更新

我已经接受了下面的Nader回答,但这似乎不是正确的方法,因为它没有在dataSource上调用 rowHasChanged。它也不符合ListView文档。它确实解决了我的问题,所以我将其标记为答案,但是我感觉这是一种解决方法,而不是正确的解决方案

另一个更新

好的,这很尴尬,但是我的 rowHasChanged函数缺少 return语句。我猜咖啡中的ES6糖过多。

因此,总而言之,如果您破坏了 rowHasChanged函数,则出于某些原因 this._ds会起作用。如果您以正确的方式开始工作,则应该使用类似以下内容的方法:
this.setState({
dataSource: this.state.dataSource.cloneWithRows(rows)
});

在更新 dataSource时。

还要记住,您需要一个新的 rows datablob。用 cloneWithRows(rows.push(newRow)之类的方法将其原地突变将不起作用,而 cloneWithRows(rows.concat([newRow])则将其起作用。

最佳答案

我认为问题在于您正在基于先前的ListView.DataSource实例设置数据源。我已经建立了一个关于here的演示,并将示例放在下面的示例中。

尝试这样做:

'use strict';

var React = require('react-native');
var {
AppRegistry,
StyleSheet,
Text,
View,
TouchableOpacity,
ListView
} = React;

var ds = new ListView.DataSource({rowHasChanged: (r1, r2) => { r1 !== r2 }});

var SampleApp = React.createClass({

getInitialState() {
var rows = ['row 1', 'row 2', 'row 3'];
return {
dataSource: ds.cloneWithRows(rows),
};
},

_deleteRow() {
var rows = ['row 1', 'row 3'];
this.setState({dataSource: ds.cloneWithRows(rows)})
},

renderRow(rowData, sectionID, rowID) {
return <TouchableOpacity onPress={this._deleteRow}
style={{height: 60, flex: 1, borderBottomWidth: 1}}>
<Text>{rowData}</Text>
</TouchableOpacity>
},

render() {
return (
<ListView
dataSource={this.state.dataSource}
renderRow={this.renderRow}
/>
);
}

});

https://rnplay.org/apps/YGBcIA

您还可以在renderRow中使用rowID来标识要删除的项目,然后在Delete函数中重置dataSource的状态。

查看我设置了 here的示例。另外,代码如下:
'use strict';

var React = require('react-native');
var {
AppRegistry,
StyleSheet,
Text,
View,
TouchableOpacity,
ListView
} = React;

var rows = ['row 1', 'row 2', 'row 3'];
var ds = new ListView.DataSource({rowHasChanged: (r1, r2) => {
r1 !== r2
}});

var SampleApp = React.createClass({

getInitialState() {

return {
dataSource: ds.cloneWithRows([]),
rows: rows
};
},

componentDidMount() {
this.setState({
dataSource: ds.cloneWithRows( this.state.rows )
})
},

_deleteRow(rowID) {
this.state.rows.splice(rowID, 1)
this.setState({
dataSource: ds.cloneWithRows( this.state.rows ),
})
},

renderRow(rowData, sectionID, rowID) {
return <TouchableOpacity onPress={ () => this._deleteRow(rowID) }
style={{height: 60, flex: 1, borderBottomWidth: 1}}>
<Text>{rowData}</Text>
</TouchableOpacity>
},

render() {
return (
<ListView
dataSource={this.state.dataSource}
renderRow={this.renderRow}
/>
);
}

});
var styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#F5FCFF',
},
welcome: {
fontSize: 28,
textAlign: 'center',
margin: 10,
},
instructions: {
textAlign: 'center',
color: '#333333',
fontSize: 19,
marginBottom: 5,
},
});

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

关于listview - react native ListView : Wrong row removed when deleting,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35411797/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com