条件・関連リソース
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.5
react-native-paper 3.6.0
react-redux 7.2.0
redux 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'; ...
barStyle
display
none
。。なるほど! - 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 の設定方法の詳細は別の記事になっていますので、興味のある方はご参考ください。
コメント