Компонент React-Native не будет повторно отображаться на setState, пока активен исходный рендер
В моем конструкторе компонентов я загружаю список "вех" и количество дней, с тех пор как кто-то бросил курить. Вехи жестко запрограммированы и загружаются синхронно. Количество дней загружается из AsyncStorage. Мой компонент отображает AndroidProgressBar для каждого этапа, где прогресс для каждого индикатора выполнения this.state.days / milestone.duration
, Во время рендеринга число дней возвращается асинхронно, и состояние обновляется с помощью setState({days})
, Измененное состояние не запускает рендеринг, я полагаю, потому что он находится в середине оригинального рендера. Это приводит к тому, что индикаторы выполнения для большинства этапов являются неверными.
Я прошел через отладчик и вижу, что число дней обновляется прямо перед тем, как были обработаны последние 2 вехи, что делает только их правильными.
Вот мой компонент.
import React, {Component} from 'react';
import {AppRegistry, StyleSheet, Alert, AsyncStorage} from 'react-native';
import { Container, Header, Content, Body, List, Title} from 'native-base';
import MilestoneItem from '../../components/MilestoneItem/MilestoneItem';
export default class MilestoneScreen extends Component {
constructor(props) {
super(props);
this.state = {
milestones:[ ],
days: 0
};
/* shape of milestones = [{title: str, duration: number}, ... ] */
this.state.milestones = this.sortByDuration(props.storageManager.milestones());
this.getDays();
}
async getDays() {
let settings = await AsyncStorage.getItem("settings");
settings = JSON.parse(settings);
this.setState({days: settings.days});
}
// Sort the milestones by their duration.
sortByDuration(array) {
return array.sort(function(a, b) {
var x = a.duration;
var y = b.duration;
return ((x < y) ? -1 : ((x > y) ? 1 : 0));
});
}
render() {
return (
<Container>
<Content>
<List dataArray={this.state.milestones}
renderRow={ (item) => {
let progress = item.duration > this.state.days ? this.state.days / item.duration : 1;
return <MilestoneItem milestone={item.title} progress={progress} />
}
}
/>
</Content>
</Container>
);
}
}
AppRegistry.registerComponent('MilestoneScreen', () => MilestoneScreen);
Вот несколько экранов поведения отладчика. Эта фотография показывает начало функции рендера.
Это фото показывает, что после вызова getDays() состояние успешно сохраняется.
Это фото показывает, что this.state.days обновился, но функция рендеринга не перезапустилась. Вместо этого он просто продолжил там, где остановился.
Эта фотография показывает окончательный результат с каждым неверным этапом, за исключением последних 2.
1 ответ
Компонент List из React-Native запускает повторное рендеринг при обновлении поля dataArray, а не для чего-либо в функции renderRow. Вы должны обновить состояние поля dataArray, чтобы вызвать повторное рендеринг.
Тег для удобного поиска: список компонентов не отображается.