我有一个自定义SectionList
组件,称为EventSectionList
:
import React from 'react';
import { SectionList } from 'react-native';
import { View, Text, Fab } from '../../../common/Layout';
import EventCard from '../EventCard';
import styles from './styles';
const EventSectionList = ({
sections,
refreshing,
onRefresh,
onEndReached,
onFabPress,
inExtraData,
}) => {
const renderSectionHeader = ({ section: { title } }) => (
<Text style={styles.sectionHeader}>{title}</Text>
);
const renderSectionFooter = () => <View style={styles.sectionSeparator} />;
const renderSeparator = () => <View style={styles.itemSeparator} />;
const renderFooter = () => <View style={styles.footer} />;
const renderEvent = event => {
const { item } = event;
return <EventCard event={item} />;
};
return (
<View style={styles.container}>
<SectionList
sections={sections}
refreshing={refreshing}
onRefresh={onRefresh}
onEndReachedThreshold={0}
onEndReached={onEndReached}
renderItem={renderEvent}
renderSectionHeader={renderSectionHeader}
renderSectionFooter={renderSectionFooter}
ItemSeparatorComponent={renderSeparator}
ListFooterComponent={renderFooter}
showsVerticalScrollIndicator={false}
extraData={inExtraData}
keyExtractor={(item, index) => String(index)}
/>
<Fab icon="add" style={styles.fabAdd} onPress={onFabPress} />
</View>
);
};
export default EventSectionList;
AnEventSectionList
正在此处呈现EventsScreen
:
import React, { useState, useEffect, Fragment } from 'react';
import { isEmpty } from 'lodash';
import { Text } from '../../../common/Layout';
import { connect } from './../../../common/Helpers';
import EventSectionList from './../../Events/EventSectionList';
import styles from './styles';
const EventsScreen = ({ services }) => {
const { eventsService } = services;
const [hostedEvents, setHostedEvents] = useState([]);
const [registeredEvents, setRegisteredEvents] = useState([]);
const [eventSections, setEventSections] = useState(null);
const [refreshing, setRefreshing] = useState(false);
const [page, setPage] = useState(1);
useEffect(() => {
if (!isEmpty(eventSections)) {
setRefreshing(false);
}
}, [eventSections]);
useEffect(() => {
if (!isEmpty(hostedEvents) || !isEmpty(registeredEvents)) {
setEventSections([
{
title: 'Upcoming Hosted Events',
data: hostedEvents,
},
{
title: 'Upcoming Registered Events',
data: registeredEvents,
},
]);
}
}, [hostedEvents, registeredEvents]);
useEffect(() => {
const hostedEventsPromise = async () => {
const { data } = await eventsService.getEvents({
page,
hosted: true,
upcoming: true,
page_size: 100,
});
if (page === 1) {
setHostedEvents(data);
} else {
setHostedEvents([...hostedEvents, ...data]);
}
};
const registeredEventsPromise = async () => {
const { data } = await eventsService.getEvents({
page,
hosted: false,
upcoming: true,
page_size: 100,
});
if (page === 1) {
setRegisteredEvents(data);
} else {
setRegisteredEvents([...registeredEvents, ...data]);
}
};
registeredEventsPromise();
hostedEventsPromise();
}, [page]);
const eventsRefresh = async () => {
if (!refreshing) {
setPage(1);
}
};
const eventsRefreshEnd = async () => {
if (!refreshing) {
setPage(page + 1);
}
};
return (
<Fragment>
{eventSections ? (
<EventSectionList
sections={eventSections}
inExtraData={registeredEvents}
refreshing={refreshing}
onRefresh={eventsRefresh}
onEndReached={eventsRefreshEnd}
onFabPress={() => {}}
/>
) : (
<Text style={styles.message}>You have no upcoming events.</Text>
)}
</Fragment>
);
};
export default connect()(EventsScreen);
不幸的是,有时 - Registered Events 部分不会呈现,直到下拉刷新发生,即使这样 - 它并不总是呈现。我可以看到这部分有点试图渲染 - EventCards 在应该渲染的地方闪烁,但它们不会“粘住”。
作为参考,这里是EventCard
组件:
import React, { useState } from 'react';
import { isEmpty } from 'lodash';
import moment from 'moment';
import { connect } from '../../../common/Helpers';
import { View, Text, Touchable } from '../../../common/Layout';
import { Image } from '../../../common/Image';
import styles from './styles';
const EventCard = ({ event }) => {
const dateFormat = 'MMM D';
const timeFormat = 'h:mm A';
const [startDate] = useState(
moment(event.start_date)
.format(dateFormat)
.toUpperCase()
);
const [startTime] = useState(moment(event.start_date).format(timeFormat));
const [startDateTime] = useState(`${startDate} AT ${startTime}`);
const [name] = useState(event.name);
const [address] = useState(
event.start_location && event.start_location.address
);
const [uri] = useState(event.cover_image);
return (
<Touchable>
<View style={styles.container}>
{!isEmpty(uri) ? (
<Image source={{ uri }} style={styles.detailsImage} />
) : (
<Image name="eventPlaceholder" style={styles.detailsImage} />
)}
<View style={styles.detailsContainer}>
<Text style={styles.detailsDate}>{startDateTime}</Text>
<Text style={styles.detailsName}>{name}</Text>
<Text style={styles.detailsAddress}>{address}</Text>
</View>
</View>
</Touchable>
);
};
export default connect()(EventCard);