react-native - 使用 react-navigation 处理组件重新安装(相同的实现,不同的结果)
问题描述
我有一个似乎无法解决的问题。
我有一个使用 react-native 和 expo 以及 react-navigation 构建的应用程序。我想要实现的目标:用户可以注册一个活动。用户想要参与的所有事件都列在一个屏幕上。按下一个按钮将此事件标记为“活动” - 用户现在可以(在另一个屏幕上)查看此事件的详细信息和公告板。
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 将设置活动事件 ID。如果和以前一样,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 ( ... );
};
这一次,每次我导航到公告屏幕时,都会使用初始状态(null),因此会触发重新加载,这不是我想要的。我使用堆栈导航和 native-base 作为页脚选项卡导航,用于在详细信息和公告屏幕之间导航。我有一个盲点吗?这是相同的实现,对吗?为什么它的行为不同?
解决方案
跟进:堆栈导航就是这样工作的……标签导航没有。所以它适用于标签导航。