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

React Navigation:当前已打开页面点击抽屉按钮时重置页面

React Navigation抽屉导航:点击当前活跃页面的抽屉按钮时重置页面或触发事件

方案1:通过replace重置页面(重新挂载组件)

这种方式会直接替换当前路由,让组件重新挂载,从而达到重置页面的效果。修改你的Drawer.Screen配置:

import React from "react";
import { NavigationContainer } from "@react-navigation/native";
import GameScreen from "./screens/GameScreen";
import { createDrawerNavigator } from "@react-navigation/drawer";

export default function App() {
  const Drawer = createDrawerNavigator();

  return (
    <NavigationContainer>
      <Drawer.Navigator useLegacyImplementation initialRouteName="Home">
        <Drawer.Screen
          name="Home"
          options={{
            title: "HomePage",
            unmountOnBlur: true,
          }}
          component={GameScreen}
          listeners={{
            drawerItemPress: (e) => {
              const currentRoute = e.navigation.getCurrentRoute()?.name;
              // 判断点击的是否是当前活跃页面
              if (currentRoute === e.route.name) {
                // 使用replace重新加载当前页面
                e.navigation.replace(e.route.name);
              }
            },
          }}
        />
        <Drawer.Screen 
          name="Nuevo juego" 
          component={GameScreen}
          listeners={{
            drawerItemPress: (e) => {
              const currentRoute = e.navigation.getCurrentRoute()?.name;
              if (currentRoute === e.route.name) {
                e.navigation.replace(e.route.name);
              }
            },
          }}
        />
      </Drawer.Navigator>
    </NavigationContainer>
  );
}

说明:

  • drawerItemPress 监听抽屉项的点击事件
  • 通过 getCurrentRoute() 获取当前活跃的路由名称,和点击的路由名称对比
  • 如果是同一个页面,调用 navigation.replace() 替换当前路由,组件会重新挂载,实现重置效果

方案2:向页面发送自定义事件(灵活处理重置逻辑)

如果不想重新挂载组件,而是让页面内部处理重置逻辑,可以通过导航事件系统发送自定义事件:

第一步:修改App中的抽屉监听器

// ... 其他代码不变
<Drawer.Screen
  name="Home"
  options={{ title: "HomePage" }}
  component={GameScreen}
  listeners={{
    drawerItemPress: (e) => {
      const currentRoute = e.navigation.getCurrentRoute()?.name;
      if (currentRoute === e.route.name) {
        // 发送自定义重置事件
        e.navigation.emit('resetCurrentScreen', { screen: e.route.name });
      }
    },
  }}
/>
<Drawer.Screen 
  name="Nuevo juego" 
  component={GameScreen}
  listeners={{
    drawerItemPress: (e) => {
      const currentRoute = e.navigation.getCurrentRoute()?.name;
      if (currentRoute === e.route.name) {
        e.navigation.emit('resetCurrentScreen', { screen: e.route.name });
      }
    },
  }}
/>
// ... 其他代码不变

第二步:在GameScreen中订阅事件并处理重置

import React, { useEffect, useState } from "react";
import { View, Text, Button } from "react-native";

const GameScreen = ({ navigation }) => {
  const [score, setScore] = useState(0);

  // 订阅自定义重置事件
  useEffect(() => {
    const unsubscribe = navigation.addListener('resetCurrentScreen', () => {
      // 执行页面内部的重置逻辑,比如恢复初始状态
      setScore(0);
      console.log('页面已重置');
    });

    // 组件卸载时取消订阅
    return unsubscribe;
  }, [navigation]);

  return (
    <View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
      <Text>当前分数:{score}</Text>
      <Button title="加分" onPress={() => setScore(prev => prev + 1)} />
    </View>
  );
};

export default GameScreen;

说明:

  • 使用 navigation.emit() 发送自定义事件,携带需要的参数(可选)
  • 在页面中通过 navigation.addListener() 订阅事件,收到事件后执行自定义的重置逻辑
  • 这种方式更灵活,不需要重新挂载组件,适合需要保留部分状态或避免重新渲染开销的场景

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 11:35:29