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

Flutter:使用go_router与Riverpod时底部导航栏点击无响应的状态管理问题

解决Flutter中Riverpod+GoRouter底部导航栏点击无响应的问题

Hey, let's break down what's causing this issue and fix it step by step!

问题根源

The core problem is in your LoggedScreen widget: you're using Future.delayed(Duration.zero) to handle route navigation based on indexProvider state, but this code only runs once when the widget first builds. When you tap the bottom navigation bar to update indexProvider, the widget doesn't re-run this delayed logic, so no navigation happens. Only when you hot reload or re-login (which rebuilds LoggedScreen entirely) does this code execute again—hence why it works in those scenarios.

解决方案

We need to properly listen to changes in indexProvider and sync the route state with the bottom navigation bar's selected index (and vice versa) to keep everything consistent.

1. Replace Future.delayed with ref.listen

Update your LoggedScreen widget to use ref.listen to react to index changes immediately:

class LoggedScreen extends HookConsumerWidget {
  const LoggedScreen({super.key, required this.screenName});

  final String screenName;

  // Helper to map screen names to navigation indices
  int _getIndexFromScreenName(String name) {
    switch (name) {
      case 'home': return 0;
      case 'game': return 1;
      case 'event': return 2;
      case 'profile': return 3;
      default: return 0;
    }
  }

  @override
  Widget build(BuildContext context, WidgetRef ref) {
    // 1. Listen for index changes and navigate to the corresponding route
    ref.listen<int>(indexProvider, (previousIndex, newIndex) {
      switch (newIndex) {
        case 0: context.go('/home'); break;
        case 1: context.go('/game'); break;
        case 2: context.go('/event'); break;
        case 3: context.go('/profile'); break;
      }
    });

    // 2. Sync navigation index with current route (for deep links or direct route changes)
    final currentIndex = _getIndexFromScreenName(screenName);
    ref.read(indexProvider.notifier).state = currentIndex;

    return Scaffold(
      appBar: AppBar(
        title: const Text("Ludocal 2"),
        backgroundColor: Colors.deepOrangeAccent,
        actions: [
          TextButton.icon(
            icon: const Icon(Icons.logout_rounded, color: Colors.white),
            label: const Text('', style: TextStyle(color: Colors.white)),
            onPressed: () async {
              ref.read(loginControllerProvider.notifier).signOut();
            },
          ),
        ],
      ),
      body: BodyTab(screenName: screenName),
      bottomNavigationBar: const BottomTab(),
    );
  }
}

2. Update BottomTab to watch the index state

Modify your BottomTab to use ref.watch instead of ref.read so it automatically updates when the index changes:

class BottomTab extends ConsumerWidget {
  const BottomTab({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context, WidgetRef ref) {
    final currentIndex = ref.watch(indexProvider); // Use watch here for auto-updates
    return BottomNavigationBar(
      currentIndex: currentIndex,
      onTap: (int index) => ref.read(indexProvider.notifier).state = index,
      backgroundColor: Colors.deepOrangeAccent,
      items: const <BottomNavigationBarItem>[
        BottomNavigationBarItem(icon: Icon(Icons.home), label: 'Home'),
        BottomNavigationBarItem(icon: Icon(Icons.emoji_emotions), label: 'Game'),
        BottomNavigationBarItem(icon: Icon(Icons.calendar_today_rounded), label: 'Event'),
        BottomNavigationBarItem(icon: Icon(Icons.person), label: 'Profile'), // Added missing profile item
      ],
    );
  }
}

为什么这样有效?

  • ref.listen triggers every time indexProvider changes, so tapping the bottom navigation bar will immediately trigger route navigation.
  • Syncing the index with the current route ensures that if the user navigates directly to a route (e.g., via a deep link), the bottom navigation bar shows the correct selected item.
  • Using ref.watch in BottomTab makes the selected index update automatically whenever indexProvider changes, keeping the UI in sync.

额外建议

I added the missing 'Profile' item to your bottom navigation bar—your route includes a /profile path, but the original bar only had 3 items, which would have caused index mismatches.

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.27 18:44:06