我使用react-native-tab-view和react-native-calendars。
问题是我不完全了解选项卡更改时的情况。
我有两个标签,一个-来自react-native-calendars的议程组件。 每次重新加载议程(重新安装和卸载)时更改标签时,都会收到警告:
警告:无法在已卸载的设备上调用setState(或forceUpdate) 零件。这是空操作,但表示您的内存泄漏 应用。要修复,请取消所有订阅和异步任务 在componentWillUnmount方法中。 在AgendaView中(在CalendarBlock.js:136处) 在RCTView中(在View.js:60) 在视图中(在CalendarBlock.js:135处) 在CalendarBlock中(位于MainScreen.js:179) 秒(由SceneComponent创建)
这是TabView组件代码:
export default class MainScreen extends Component {
constructor(props) {
super(props);
this.state = {
index: 0,
routes: [
{ key: 'first', title: 'Drugs Screen' },
{ key: 'second', title: 'Calendar Screen' },
],
}
}
_renderTabBar = props => {
const inputRange = props.navigationState.routes.map((x, i) => i);
return (
<View style={styles.tabBar}>
{props.navigationState.routes.map((route, i) => {
const color = props.position.interpolate({
inputRange,
outputRange: inputRange.map(
inputIndex => (inputIndex === i ? '#D6356C' : '#222')
)
});
return (
<TouchableOpacity
key={i}
style={styles.tabItem}
onPress={() => this.setState({ index: i })}>
<Animated.Text style={{ color }}>{route.title}</Animated.Text>
</TouchableOpacity>
);
})}
</View>
);
};
render() {
const { notificationsData, calendarData } = this.props;
const { calendarIsActive } = this.state;
return (
<TabView
navigationState={this.state}
renderScene={SceneMap({
first: () => <DrugsListBlock navigation={this.props.navigation}/>,
second: () => <CalendarBlock notificationsData={notificationsData} calendarData={calendarData}/>
})}
renderTabBar={this._renderTabBar}
onIndexChange={index => this.setState({ index })}
initialLayout={{ height: 0, width: Dimensions.get('window').width }}
/>
)
}
}
这是我的日历组件代码:
export default class CalendarBlock extends Component {
constructor(props) {
super(props);
this.state = {
items: {}
};
this.loadItems = this.loadItems.bind(this);
}
timeToString(time) {
const date = new Date(time);
return date.toISOString().split('T')[0];
}
loadItems(day) {
const { items } = this.state;
const { notificationsData } = this.props;
// Load monthly data with 1000ms timeoute;
setTimeout(() => {
// Margin of -15 < i (days) < 30 for smooth loading
for (let i = -15; i < 30; i++) {
// To UTC+3 fix
const threeHours = 3 * 60 * 60 * 1000;
const margin = i * 24 * 60 * 60 * 1000;
const dateTimestamp = day.timestamp + margin;
const dateString = this.timeToString(dateTimestamp);
// Create each date empty array
!items[dateString] && (
items[dateString] = []
);
// Map through notifications data array
notificationsData.forEach(item => {
// Here i form items new object
})
}
const newItems = Object.assign({}, items);
this.setState({
items: newItems
});
}, 1000 );
}
render() {
return (
<Agenda
style={{width: Dimensions.get('window').width}}
items={this.state.items}
loadItemsForMonth={(day) => this.loadItems(day)}
renderItem={item => <CalendarItem item={item}/>}
renderEmptyDate={item => <CalendarEmptyItem/>}
rowHasChanged={(r1, r2) => r1.name !== r2.name}
/>
);
}
}
我希望在loadItems方法中异步任务超时,但是清除它并不能解决警告。或者,也许我以错误的方式清除了它?
let timeout;
loadItems(day) {
// Load monthly data with 1000ms timeoute;
timeout = setTimeout(() => {
....same code...
componentWillUnmount() {
clearTimeout(timeout);
}
...same code..
我想也许有一种方法可以不卸载TabView场景?每次都在重新加载议程时,每次看到正在加载微调框并等待它。
或者至少我可以在超时的情况下做其他事情?
感谢您的帮助。