条件・関連リソース
React Navigation v5 + React Native Paper を使い React Native アプリを開発する時、createMaterialBottomTabNavigator で作成した Tab を非表示にするため、tabBarVisible: false オプションを使っても何故か効かなかったので調べてみたら以下の公式サイトでは material-bottom-tabs だけ tabBarVisible オプションが見当たらなかったし、ネットで検索しても古い情報しかなかったので自分のやり方で解決 ( 回避 ) してみました。
以下は公式サイト:
- React Native Paper > BottomNavigation
- React Navigation > createMaterialBottomTabNavigator
条件:
- Redux ToolkitでReduxを楽に使う〜React-Native〜 の「方法 #4:RTK + Redux Hooks」 を利用し設定します。
- Stack Screen の
HeaderはReact Native PaperのAppbarを利用しています。 - この記事の内容は
material-bottom-tabsだけに該当します。
関連リソース:
@react-navigation/material-bottom-tabs 5.1.0@react-navigation/native 5.0.8@react-navigation/stack 5.1.0@reduxjs/toolkit 1.2.5react-native-paper 3.6.0react-redux 7.2.0redux 4.0.5- など。。
実現したいこと!
MaterialBottomTab ( Parent Navigator )
└─ HomeStack ( Child Navigator )
└─ Home Screen
└─ Details Screen ◀︎このスクリーンを開くと Tab を非表示にしたい!
設定方法
- Step 1解決方法を見つける
この記事は Tab bar can now be hidden #20 のリンクから始まりました。
... if (!this._isVisible()) { barStyle['display'] = 'none'; ...barStyledisplaynone。。なるほど! - Step 2barStyle オブジェクトを設定します。
const MaterialBottomTab = createMaterialBottomTabNavigator();で作成したファイルが対象です。以下の
barStyleオブジェクトにisTabVisible変数がfalseになると Tab を隠すように設定を追加します。( 変数名はすべて任意 )// 'none'ではないと、効きません! ... return ( <MaterialBottomTab.Navigator initialRouteName={INITIAL_ROUTE_NAME} barStyle={{ display: isTabVisible ? null : "none" }} ... - Step 3Tab の条件をコントロールする State 値を設定します。
ここで Redux Store を利用します。( 詳細:方法 #4:RTK + Redux Hooks )
useSlice で Reducer を作成します。
- Tab の初期状態 (
isTabVisible) を表示 (true) に。 - アクションクリエーター:
setTabVisibility - State 値:
action.payload
// MaterialBottomTabSlice.js import { createSlice } from "@reduxjs/toolkit"; const MaterialBottomTabSlice = createSlice({ name: "MaterialBottomTab Control", initialState: { isTabVisible: true }, reducers: { setTabVisibility: (state, action) => { Object.assign(state, { isTabVisible: action.payload }); } } }); export const { setTabVisibility } = MaterialBottomTabSlice.actions; export default MaterialBottomTabSlice.reducer;MaterialBottomTabNavigator を設定します。
Parent Navigator :
useSelectorを利用し State 値isTabVisibleを取得します。取得した State 値で以下のように条件分岐します。
▶︎display: isTabVisible ? null : "none"// MaterialBottomTabs.js 抜粋 import { useSelector } from "react-redux"; const MaterialBottomTab = createMaterialBottomTabNavigator(); export function MaterialBottomTabsScreen() { const isTabVisible = useSelector(state => state.tabs.isTabVisible); .. return ( <MaterialBottomTab.Navigator initialRouteName={INITIAL_ROUTE_NAME} barStyle={{ backgroundColor: theme.dark ? activeSurfaceColor : theme.colors.primary, display: isTabVisible ? null : "none" }} - Tab の初期状態 (
- Step 4Stack Screenを設定します。
Child Screen :
Tab を隠すスクリーンで State 値を設定します。
Home Screen から Details Screen に遷移すると、
useEffectを使いsetTabVisibilityアクションクリエーターをdispatchしてRedux Storeを更新します。dispatch(setTabVisibility(false));することで Tab が非表示に変わります。また、
Details Screenから離れる場合はtrueに戻します。下記の例では
Go to Homeボタンをタップすると Tab が表示されます。// Details.js import { setTabVisibility } from "redux/reducers/MaterialBottomTabSlice"; import { useDispatch } from "react-redux"; ... function DetailsScreen({ navigation }) { const dispatch = useDispatch(); React.useEffect(() => { dispatch(setTabVisibility(false)); }, []); return ( <JScrollView> <View style={{ alignItems: "center", justifyContent: "center" }}> <JText>Details Screen</JText> <Button onPress={() => { navigation.navigate("Home"); dispatch(setTabVisibility(true)); }} mode="outlined" > Go to Home </Button>画面左上の Back ボタンをタップする場合も設定します。
<Appbar.BackAction/>にdispatch(setTabVisibility(true));を追加すれば OK です。import { Appbar, Avatar } from "react-native-paper"; import { setTabVisibility } from "redux/reducers/MaterialBottomTabSlice"; import { useDispatch } from "react-redux"; const JAppbarHeader = ({ scene, previous, navigation }) => { const dispatch = useDispatch(); .. {previous ? ( <Appbar.BackAction onPress={() => { navigation.goBack(); dispatch(setTabVisibility(true)); }} /> ...これで設定は完了です!
動作確認
Redux Store の設定は以下の通りです。
...
const rootReducer = combineReducers({
tabs: MaterialBottomTabReducer
});
...
まとめ
React navigation で material-bottom-tabs に tabBarVisible が使えなくても以上のやり方でも臨機応変策としては有効かと思います。( Android / iOS )
また、Redux Store の設定方法の詳細は別の記事になっていますので、興味のある方はご参考ください。


コメント