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

React Navigation自定义抽屉不重绘:切换项时样式未更新

解决React Navigation自定义抽屉组件样式不更新的问题

我之前也碰到过一模一样的问题!你遇到的核心问题是依赖props.activeItemKey来判断激活状态不可靠,这个属性并不会在路由切换时自动触发组件重渲染,导致你的样式切换逻辑失效。下面是具体的排查和修复方案:

问题根源

在自定义抽屉组件DrawerScreen中,你通过props.activeItemKey对比菜单项的key来设置样式,但React Navigation的自定义contentComponent并不会实时更新这个activeItemKey属性,或者说这个属性的更新没有触发组件的重绘,导致切换菜单时样式不会变化。另外注意你的组件名拼写错误:DrawserScreen应该是DrawerScreen,虽然大概率是笔误,但也可能影响组件的正常渲染。

修复方案:直接从导航状态获取当前激活路由

我们可以直接从导航实例的状态中获取当前活跃的路由信息,这样就能实时响应路由切换,触发样式更新。

针对React Navigation 5+版本(推荐)

使用useNavigation和useRoute钩子来获取当前路由状态:

import React from 'react';
import { ScrollView, SafeAreaView, TouchableHighlight, View, Text } from 'react-native';
import { useNavigation, useRoute } from '@react-navigation/native';

const DrawerScreen = props => {
  const navigation = useNavigation();
  const currentRoute = useRoute();
  const totalitem = props.items;

  return(
    <ScrollView style={{backgroundColor:'#000'}}>
      <SafeAreaView forceInset={{ top: 'always', horizontal: 'never' }}>
        { totalitem.map((ritem,i)=>{
          // 对比路由名称,更直观可靠
          const isActive = ritem.routeName === currentRoute.name;
          const txtstyle = isActive ? styles.draweritemstxt_active : styles.draweritemstxt_inactive;

          return(
            <TouchableHighlight 
              key={i} 
              activeOpacity={0.9} 
              onPress={()=> props.navigation.navigate(ritem.routeName)} 
              style={styles.draweritems}
            >
              <View>
                <Text style={txtstyle}>{_convertRouteToTitle(ritem.routeName)}</Text>
              </View>
            </TouchableHighlight>
          );
        }) }
      </SafeAreaView>
    </ScrollView>
  );
}

// 别忘了定义你的样式
const styles = {
  draweritems: {
    // 你的菜单项容器样式
  },
  draweritemstxt_active: {
    color: '#fff',
    fontWeight: 'bold',
    // 其他激活样式
  },
  draweritemstxt_inactive: {
    color: '#aaa',
    // 其他未激活样式
  }
};

export default DrawerScreen;

针对React Navigation 4及以下版本

如果还在使用旧版本,可以直接从props.navigation.state中获取当前活跃路由:

const DrawerScreen = props => {
  // 获取当前活跃路由的key
  const currentActiveKey = props.navigation.state.routes[props.navigation.state.index].key;
  const totalitem = props.items;

  return(
    <ScrollView style={{backgroundColor:'#000'}}>
      <SafeAreaView forceInset={{ top: 'always', horizontal: 'never' }}>
        { totalitem.map((ritem,i)=>{
          const txtstyle = ritem.key === currentActiveKey 
            ? styles.draweritemstxt_active 
            : styles.draweritemstxt_inactive;

          return(
            <TouchableHighlight 
              key={i} 
              activeOpacity={0.9} 
              onPress={()=> props.navigation.navigate(ritem.key)} 
              style={styles.draweritems}
            >
              <View>
                <Text style={txtstyle}>{_convertRouteToTitle(ritem.routeName)}</Text>
              </View>
            </TouchableHighlight>
          );
        }) }
      </SafeAreaView>
    </ScrollView>
  );
}

额外检查点

  • 确认styles.draweritemstxt_active和styles.draweritemstxt_inactive确实有明显的样式差异(比如颜色、字体粗细),避免因为样式本身无区别导致看起来没变化。
  • 确保_convertRouteToTitle函数能正确转换路由名称,不影响渲染逻辑。

这样修改后,切换抽屉选项时,组件会实时获取当前活跃路由,正确应用激活/未激活样式,触发重绘。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 08:42:19