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

无需Redux等状态管理器,如何可靠刷新Drawer Navigator?

解决Drawer导航随用户角色动态更新的问题

问题核心原因

  1. App.js中userRole仅在组件初始化时赋值一次,后续用户登录状态变化不会重新计算,导致抽屉导航无法更新。
  2. 导出的getUserRole函数通过创建新的Dashboard实例获取角色,和页面上实际渲染的Dashboard组件并非同一个实例,无法拿到真实的用户角色状态。
  3. Dashboard组件的角色状态是内部私有状态,没有同步到上层的DrawerNavigator组件。

解决方案(无需Redux,用React Context实现状态共享)

步骤1:创建用户角色Context

新建UserRoleContext.js文件,统一管理用户角色状态并监听登录变化:

import React, { createContext, useContext, useState, useEffect } from 'react';
import { FIREBASE_AUTH } from './path-to-your-firebase-config'; // 替换为你的Firebase配置路径

const UserRoleContext = createContext();

export const UserRoleProvider = ({ children }) => {
  const [userRole, setUserRole] = useState('user');

  useEffect(() => {
    // 监听Firebase用户登录状态变化
    const unsubscribe = FIREBASE_AUTH.onAuthStateChanged((user) => {
      if (user) {
        // 沿用你原有的角色判断逻辑
        if (user.displayName === "Sth" && user.email === "sth@sth.com") {
          setUserRole('admin');
        } else {
          setUserRole('user');
        }
      } else {
        // 未登录时设为默认角色
        setUserRole('user');
      }
    });

    // 组件卸载时清理监听
    return () => unsubscribe();
  }, []);

  return (
    <UserRoleContext.Provider value={{ userRole }}>
      {children}
    </UserRoleContext.Provider>
  );
};

// 自定义Hook,方便其他组件获取角色
export const useUserRole = () => useContext(UserRoleContext);

步骤2:修改App.js,接入Context

让DrawerNavigator从Context中获取实时角色,实现动态渲染:

import { UserRoleProvider, useUserRole } from './UserRoleContext';
import Dashboard from './components/dashboard';
// 导入其他所需组件(如Drawer、HeaderLogo等)

function DrawerNavigator() {
  const { userRole } = useUserRole(); // 从Context获取实时角色

  return (
    <>
      <Drawer.Navigator
        screenOptions={{
          drawerActiveTintColor: "#000",
          fontWeight: "bold",
        }}
        initialRouteName="Home"
        drawerContent={props => <DrawerHeader {...props} />}
      >
        <Drawer.Screen
          name="Dashboard"
          component={Dashboard}
          options={{
            headerTitle: () => <HeaderLogo />,
            headerStyle: {
              backgroundColor: "#FEF202",
            },
            headerTitleAlign: "center",
            drawerIcon: () => (
              <AntDesign name="dashboard" size={30} color="black" />
            ),
          }}
        />
        {/* 注意:原代码是角色为user时显示管理项,若需管理员才显示,将条件改为`userRole === "admin"` */}
        {userRole === "user" && (
          <>
            <Drawer.Screen
              name="Add Games"
              component={AddGamesD}
              options={{
                headerTitle: "Admin",
                headerTitleAlign: "center",
                drawerIcon: () => (
                  <View style={{ flexDirection: "row", gap: "2vw" }}>
                    <MaterialIcons
                      name="admin-panel-settings"
                      size={30}
                      color="black"
                    />
                    <Entypo name="add-to-list" size={30} color="black" />
                  </View>
                ),
              }}
            />
            <Drawer.Screen
              name="Edit Games"
              component={EditGamesD}
              options={{
                headerTitle: "Admin",
                headerTitleAlign: "center",
                drawerIcon: () => (
                  <View style={{ flexDirection: "row", gap: "2vw" }}>
                    <MaterialIcons
                      name="admin-panel-settings"
                      size={30}
                      color="black"
                    />
                    <Entypo name="edit" size={30} color="black" />
                  </View>
                ),
              }}
            />
          </>
        )}
      </Drawer.Navigator>
    </>
  );
}

export default function App() {
  return (
    <UserRoleProvider>
      <NavigationContainer>
        <DrawerNavigator />
      </NavigationContainer>
    </UserRoleProvider>
  );
}

步骤3:简化Dashboard组件

角色状态由Context统一管理,Dashboard无需再维护内部角色状态:

import { useEffect, useState } from 'react';
import { useUserRole } from '../UserRoleContext';
import { FIREBASE_AUTH } from './path-to-your-firebase-config';

export default function Dashboard() {
  const { userRole } = useUserRole(); // 若组件需要角色,直接从Context获取
  const [displayName, setDisplayName] = useState('');
  const [uid, setUid] = useState('');
  const [currentUser, setCurrentUser] = useState(null);

  useEffect(() => {
    const user = FIREBASE_AUTH.currentUser;
    if (user) {
      setDisplayName(user.displayName || "Display Name Not Set");
      setUid(user.uid);
      setCurrentUser(user);
    }
  }, []);

  // 你的Dashboard组件渲染内容
  return (
    <div>
      {/* 组件内容 */}
    </div>
  );
}

// 原导出的getUserRole函数可删除,不再需要

方案优势

  • 利用Firebase的onAuthStateChanged实时监听用户登录状态,角色变化自动同步。
  • React Context实现跨组件状态共享,状态更新时DrawerNavigator会自动重新渲染,动态调整导航项。
  • 完全基于React原生API实现,无需引入第三方状态管理库。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 19:07:16