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

如何结合React Native Router Flux实现react-native-material-bottom-navigation?

Hey Carlos, let's work through how to get react-native-material-bottom-navigation playing nicely with React Native Router Flux (RNRF) without that annoying full content reload issue.

The Core Problem

Putting the BottomNavigation in every page component means every tab press re-mounts the entire page (including the nav itself), which causes the reloads you're seeing. The fix is to move the BottomNavigation to a root layout component that wraps your RNRF scenes, so it stays mounted while only the page content switches.

Step-by-Step Implementation

Here's a concrete example of how to set this up:

1. Import Dependencies & Page Components

First, bring in all the pieces you'll need:

import React, { useState, useEffect } from 'react';
import { View, StyleSheet } from 'react-native';
import { Actions, Router, Scene } from 'react-native-router-flux';
import { BottomNavigation, BottomNavigationTab } from 'react-native-material-bottom-navigation';

// Import your screen components
import HomeScreen from './screens/HomeScreen';
import ProfileScreen from './screens/ProfileScreen';
import SettingsScreen from './screens/SettingsScreen';

2. Create a Root Layout with BottomNavigation

This layout will hold the BottomNavigation and render the active screen content:

const MainLayout = () => {
  const [activeTab, setActiveTab] = useState('home');

  // Handle tab presses to trigger RNRF Actions
  const handleTabPress = (tabId) => {
    setActiveTab(tabId);
    switch(tabId) {
      case 'home':
        Actions.home();
        break;
      case 'profile':
        Actions.profile();
        break;
      case 'settings':
        Actions.settings();
        break;
      default:
        break;
    }
  };

  // Sync active tab with RNRF scene changes (for cases like in-app navigation)
  useEffect(() => {
    const sceneListener = Actions.addListener('sceneChange', (scene) => {
      switch(scene.key) {
        case 'home':
          setActiveTab('home');
          break;
        case 'profile':
          setActiveTab('profile');
          break;
        case 'settings':
          setActiveTab('settings');
          break;
      }
    });

    // Clean up listener on unmount
    return () => sceneListener.remove();
  }, []);

  return (
    <View style={styles.container}>
      {/* Render the active screen content */}
      <View style={styles.screenContainer}>
        {Actions.currentScene === 'home' && <HomeScreen />}
        {Actions.currentScene === 'profile' && <ProfileScreen />}
        {Actions.currentScene === 'settings' && <SettingsScreen />}
      </View>
      {/* Persistent Bottom Navigation */}
      <BottomNavigation
        activeTab={activeTab}
        onTabPress={handleTabPress}
      >
        <BottomNavigationTab id="home" label="Home" icon="home" />
        <BottomNavigationTab id="profile" label="Profile" icon="account" />
        <BottomNavigationTab id="settings" label="Settings" icon="settings" />
      </BottomNavigation>
    </View>
  );
};

3. Set Up Your RNRF Router

Wire up the router to use your root layout as the initial scene:

const AppRouter = () => (
  <Router>
    <Scene key="root">
      {/* Main layout with persistent bottom nav */}
      <Scene key="main" component={MainLayout} initial />
      {/* Add non-nav screens (like login) here, they won't show the bottom nav */}
      <Scene key="login" component={LoginScreen} />
    </Scene>
  </Router>
);

// Basic styles to fill the screen
const styles = StyleSheet.create({
  container: {
    flex: 1,
  },
  screenContainer: {
    flex: 1,
  },
});

export default AppRouter;

Key Fixes Explained

  • Single BottomNavigation Instance: By placing the nav in the root layout, it only mounts once—no more reloading the nav itself when switching tabs.
  • Sync with RNRF Scenes: The sceneChange listener ensures the active tab highlights correctly even if you navigate via buttons inside your screens (not just the bottom nav).
  • No Page-Wide Nav: Remove the BottomNavigation from all your individual screen components—this eliminates the redundant mounts causing your reloads.

If you tried onPress before and it didn't work, it's likely because you were triggering navigation from a nav that was inside the screen component (which would remount everything). This approach keeps the nav separate and controls navigation at the root level.

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.22 08:17:56