You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React Navigation 6.x:能否为Stack.Screen添加onFocus函数存储当前屏幕?

在React Navigation 6.x中全局保存当前屏幕到AsyncStorage的简洁方案

方案1:全局监听导航状态变化(推荐)

无需逐个修改屏幕,直接在导航容器上监听状态变更,路由切换时自动将当前屏幕名称存入AsyncStorage,是最简洁的实现方式。

import { NavigationContainer } from '@react-navigation/native';
import AsyncStorage from '@react-native-async-storage/async-storage';

function App() {
  return (
    <NavigationContainer
      onStateChange={(state) => {
        // 获取当前活跃路由的名称
        const currentScreen = state.routes[state.index].name;
        // 存入AsyncStorage
        AsyncStorage.setItem('currentScreen', currentScreen);
      }}
    >
      <Stack.Navigator>
        <Stack.Screen
          name="ResolveAuth"
          component={ResolveAuthScreen}
          options={{ headerShown: false }}
        />
        <Stack.Screen name="Home" component={HomeScreen} />
        {/* 其他屏幕组件 */}
      </Stack.Navigator>
    </NavigationContainer>
  );
}

如果不想保存ResolveAuth这类过渡屏幕,可以在监听逻辑里过滤:

onStateChange={(state) => {
  const currentScreen = state.routes[state.index].name;
  if (currentScreen !== 'ResolveAuth') {
    AsyncStorage.setItem('currentScreen', currentScreen);
  }
}}

方案2:用高阶组件(HOC)封装屏幕追踪逻辑

如果需要按需给屏幕添加追踪(部分屏幕不需要保存),可以封装一个高阶组件,复用监听逻辑,保持原组件干净。

import { useFocusEffect } from '@react-navigation/native';
import AsyncStorage from '@react-native-async-storage/async-storage';
import React from 'react';

// 定义高阶组件
const withScreenTracker = (WrappedComponent, screenName) => {
  return (props) => {
    useFocusEffect(
      React.useCallback(() => {
        // 屏幕获取焦点时保存名称
        AsyncStorage.setItem('currentScreen', screenName);
        
        // 可选:屏幕失焦时的清理操作
        return () => {};
      }, [screenName])
    );

    return <WrappedComponent {...props} />;
  };
};

// 给需要追踪的屏幕组件套上HOC
const TrackedHomeScreen = withScreenTracker(HomeScreen, 'Home');
const TrackedResolveAuthScreen = withScreenTracker(ResolveAuthScreen, 'ResolveAuth');

// 在Stack.Screen中使用封装后的组件
<Stack.Screen
  name="ResolveAuth"
  component={TrackedResolveAuthScreen}
  options={{ headerShown: false }}
/>
<Stack.Screen name="Home" component={TrackedHomeScreen} />

方案3:直接在Stack.Screen的options中配置listener

如果你希望直接在<Stack.Screen>上完成配置,可以利用React Navigation 6.x提供的options.listener属性,监听屏幕的focus事件:

import AsyncStorage from '@react-native-async-storage/async-storage';

<Stack.Screen
  name="Home"
  component={HomeScreen}
  options={{
    listener: ({ navigation }) => {
      // 订阅focus事件
      const unsubscribe = navigation.addListener('focus', () => {
        AsyncStorage.setItem('currentScreen', 'Home');
      });
      // 组件卸载时取消订阅
      return unsubscribe;
    },
  }}
/>

// ResolveAuth屏幕同理
<Stack.Screen
  name="ResolveAuth"
  component={ResolveAuthScreen}
  options={{
    headerShown: false,
    listener: ({ navigation }) => {
      const unsubscribe = navigation.addListener('focus', () => {
        AsyncStorage.setItem('currentScreen', 'ResolveAuth');
      });
      return unsubscribe;
    },
  }}
/>

注意事项

  • AsyncStorage是异步操作,若需确保保存完成后执行后续逻辑,可在回调中使用async/await:
    navigation.addListener('focus', async () => {
      await AsyncStorage.setItem('currentScreen', 'Home');
      // 后续逻辑
    });
    

内容的提问来源于stack exchange,提问作者John

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.08 00:35:32