У меня есть проблема, которую я не могу решить.
У меня есть приложение, созданное с использованием Сборных по реакциям, Экспо и навигации. Чего я пытаюсь достичь: пользователь может подписаться на событие. Все события, которые пользователь хочет принять участие, перечислены на одном экране. Нажатие на одно помечает это событие как «активное» - теперь пользователь (на другом экране) может видеть детали и доску объявлений для этого события.
Hierarchy:
- Loginstack (not relevant, just for completion)
- Homestack
-- Home
-- Eventstack (Active Event)
--- Details
--- Bulletin Board
-- Create Event
-- Sign up for Event
-- List Events User goes to
На экране регистрации я перемещаюсь к стеку событий, пока сначала добавьте событие в локальное хранилище. Экран сведений теперь проверяет наличие активного события и загружает данные. Когда пользователь отходит от этого экрана и возвращается к нему, экран подробностей должен перезагружать данные только в том случае, если активное событие изменилось! Во-первых, Навигация по стеку:
<Stack.Navigator initialRouteName="EventDetails" headerMode="none" screenOptions={({ route, navigation}) => ({
animationEnabled: false,
})}>
<Stack.Screen
name="EventDetails"
component={EventDetailsScreen}
initialParams={{ active: EventFooter.details, }}
/>
<Stack.Screen
name="Bulletin"
component={BulletinScreen}
initialParams={{ active: EventFooter.bulletin, }}
/>
</Stack.Navigator>
Мой код:
const EventDetailsScreen = ({ navigation }) => {
const [isLoading, setLoading] = useState(true);
const [eventToLoad, setEventToLoad] = useState(null);
const [event, setEvent] = useState(null);
const userData = useContext(UserContext);
const _loadEvent = async (eId?: number) => {
setLoading(true);
let eventId: number = eId || await getActiveEvent();
if (eventId == null) {
if (userData.user.event.id === undefined) {
return;
}
eventId = userData.user.event.id;
}
const eventToSet = await findEventById(eventId);
setEvent(eventToSet);
setLoading(false);
};
const _checkEvent = async () => {
const actEvent = await getActiveEvent();
setEventToLoad(actEvent);
}
useFocusEffect(
useCallback(() => {
_checkEvent();
}, [])
);
useEffect(() => {
_loadEvent();
}, [eventToLoad]);
return ( ... );
};
Для этого кода происходит следующее. При первом переходе пользователя на экран сведений сведения о событии загружаются с сервера с помощью useEffect. Когда я сейчас перемещаюсь назад и возвращаюсь к этому экрану, useFocusEffect устанавливает идентификатор активного события. Если он такой же, как и раньше, useEffect не будет запущено ... Работает. Логи говорят то же самое. В первый раз, когда устанавливается активное событие, для всех последующих переходов к экрану сведений используются уже установленные данные. Теперь для доски объявлений (того же уровня иерархии) я реализовал ее таким же образом.
const BulletinScreen = ({ navigation }) => {
const [isLoading, setLoading] = useState(false);
const [eventToLoad, setEventToLoad] = useState(null);
const [threads, setThreads] = useState<Array<Thread>>(null);
const userData = useContext(UserContext);
const _getThreads = async () => {
setLoading(true);
let eventId: number = await getActiveEvent();
if (eventId == null) {
if (userData.user.event.id === undefined) {
return;
}
eventId = userData.user.event.id;
}
const threadsToSet = await getThreads(eventId, userData.user);
setThreads(threadsToSet);
setLoading(false);
};
const _getEvent = async () => {
const actEvent = await getActiveEvent();
setEventToLoad(actEvent);
}
useFocusEffect(
useCallback(() => {
_getEvent();
}, [])
);
useEffect(() => {
_getThreads();
}, [eventToLoad]);
return ( ... );
};
На этот раз каждый раз, когда я перехожу на экран доски объявлений, используются начальные состояния (ноль) и, следовательно, запускаются перезагрузки. что не то, что я хочу. Я использую стековую навигацию и native-base для навигации по вкладке нижнего колонтитула, которая используется для перехода между деталями и экраном бюллетеня. У меня есть слепое пятно мышления? Это та же реализация, верно? Почему он ведет себя по-другому?