React Native: ListView для повторного рендеринга только выбранного элемента, а не всего
У меня есть ListView
внутри модального, который отображает данные. Когда пользователь нажимает на элемент в этом списке, я хочу, чтобы рядом с этим элементом отображался флажок, представляющий выбранный элемент. Ошибка, которую я испытываю, заключается в том, что пользовательский интерфейс не отражает этот фактический выбор. Поэтому, когда пользователь нажимает на элемент, ничего не меняется, однако при повторном открытии модального интерфейса пользовательский интерфейс отображает галочку рядом с ранее выбранным элементом.
Исправление, которое я нашел для этого, - это сила повторного рендеринга, используя key
в ListView
, Это нормально, но если у меня есть изображения в списке, они все мигают, потому что все перерисовывается. Без настройки key
похоже на мой метод 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;
}
Возвращение:
const { selected, dataSource } = this.state;
const selectedKey = this.getKey(selected);
<ListView
key={selectedKey}
dataSource={dataSource}
renderRow={this.renderItems}
/>