首页 > 解决方案 > 使用 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 作为页脚选项卡导航,用于在详细信息和公告屏幕之间导航。我有一个盲点吗?这是相同的实现,对吗?为什么它的行为不同?

标签: react-nativereact-navigationmobile-applicationnative-base

解决方案


跟进:堆栈导航就是这样工作的……标签导航没有。所以它适用于标签导航。


推荐阅读