我在模态中有一个 self.automaticallyAdjustsScrollViewInsets = NO;
来呈现数据。当用户单击该列表中的项目时,我希望在该项目旁边显示复选框以表示该项目已被选中。我遇到的错误是UI不反映实际选择。因此,当用户点击项目时,没有任何改变,但是当重新打开模态时,UI显示先前所选项目旁边的复选标记。
我发现的修复方法是使用ListView
中的key
强制重新渲染。这没关系,但是如果我在列表中有图像,它们都会闪烁,因为一切都在重新渲染。如果不设置ListView
,看起来我的方法key
在更改(用户选择)后不会被调用。离开该键并为每个渲染项添加键似乎也没有帮助。如何在不强制重新渲染所有内容的情况下获得我期望的UI?也许我需要切换到renderItems
来控制单个列表项的渲染?
方法:
FlatList
返回:
constructor(props) {
super(props);
const ds = new ListView.DataSource({
rowHasChanged: (r1, r2) => r1 !== r2,
});
this.state = {
selected: this.parseSelected(props.data),
selectedCached: null,
dataSource: ds.cloneWithRows(props.data),
};
}
componentWillReceiveProps = nextProps => {
if (nextProps.visible) {
const saved = this.state.selected;
this.setState({
selectedCached: saved,
});
}
};
getKey = selected => {
switch (this.props.type) {
case 'SHIPPING':
return selected.code;
case 'REASON':
return selected;
case 'MULTICARDS':
return selected.account_token;
default:
return null;
}
};
parseSelected = selected => {
switch (this.props.type) {
case 'SHIPPING':
case 'REASON':
return selected[0];
case 'MULTICARDS':
return selected[this.props.selectedProduct];
default:
return null;
}
};
tempSaveSelection = selected => {
this.setState({ selected });
};
renderItems = item => {
let selected;
let body;
let style;
switch (this.props.type) {
case 'SHIPPING':
selected = this.state.selected.code === item.code;
body = <ShipItem token={item} />;
break;
case 'REASON':
selected = this.state.selected === item;
body = <FormattedMessage id={`reason_${item}`} />;
style = textSection;
break;
case 'MULTICARDS':
selected = this.state.selected.account_token === item.account_token;
body = <CardItem product={item} />;
style = textSection;
break;
default:
selected = false;
body = null;
style = null;
}