react.js
reactjs
React
reactnative

react-navigationのTabNavigatorでタップ時の挙動を変える

対象

TabNavigator使ってるけど、tabをタップした際の挙動を変更したいなんてお困りの方。

前提

$ date
2017年 8月 5日 土曜日 15時24分46秒 JST

$ react-native -v
react-native-cli: 2.0.1
react-native: 0.46.4

$ cat yarn.lock | grep "react-navigation"
react-navigation@^1.0.0-beta.11:
  resolved "https://registry.yarnpkg.com/react-navigation/-/react-navigation-1.0.0-beta.11.tgz#4271edb23cdbcc6eb88602f7fde0a77f0ef7a160"

実装内容:

Tabを二個(HomeTab, AlertTab)用意して、二個目(AlertTab)のタブがタップされたらAlertを表示する

実装例

TabBar.js
// TabBarコンポーネント
// 標準のTabBarコンポーネントをラップして、タブをタップされた際の動きを変更する

import React from "react";
import PropTypes from 'prop-types';
import { Alert } from 'react-native';
import { TabBarBottom } from 'react-navigation';

const TabBar = (props) => {
    // Tabをタップ時に呼ばれるメソッド
    const { jumpToIndex } = props
    return (
        <TabBarBottom
            {...props}
            jumpToIndex={(index) => {
                    // 二個目のタブがタップされた場合
                    if(index === 1) {
                       Alert.alert(
                    '',
                    message,
                    [
                        {text: 'Tapped Tab'},
                    ],
                    { cancelable: false }
                  )
                    } else {
                        // 標準の動作
                        jumpToIndex(index);
                    }
                }
            }
        />
    )
}

TabBar.propTypes = {
    jumpToIndex: PropTypes.func,
    navigation: PropTypes.object,
};

export default TabBar
HomeTab.js
// Homeタブコンポーネント

import React from 'react';
import PropTypes from 'prop-types';
import { View, Text } from 'react-native';
import Icon from 'react-native-vector-icons/FontAwesome';

class HomeTab extends React.Component {
    render() {
        return (
            <View>
                <Text>This is home</Text>
            </View>
        );
    }
}

function TabBarIcon({ tintColor }) {
    return (
        <Icon name="cog" color={tintColor} />
    );
}
TabBarIcon.propTypes = {
    tintColor: PropTypes.string,
};

export default HomeTab.navigationOptions = () => {
    return {
        tabBarIcon: TabBarIcon
    }
};
AlertTab.js
// Tabアイコンのみを実装
// Tabコンテンツは表示しないので、アイコンのみ

import React from 'react';
import PropTypes from 'prop-types';
import Icon from 'react-native-vector-icons/FontAwesome';

class AlertTab extends React.Component {
    render() {
        return null;
    }
}

function TabBarIcon({ tintColor }) {
    return (
        <Icon name="cog" color={tintColor} style={styles.backButton} />
    );
}
TabBarIcon.propTypes = {
    tintColor: PropTypes.string,
};

export default HomeTab.navigationOptions = () => {
    return {
        tabBarIcon: TabBarIcon
    }
};
Navigator.js
import React from "react";
import { TabNavigator } from 'react-navigation';

import TabBar from './TabBar';

import HomeTab from './HomeTab';
import AlertTab from './AlertTab';

const TabNavigatorConfig = {
    tabBarComponent: TabBar,
    {},
}

const TabView = TabNavigator({
    HomeTab : { 
        screen: HomeTab 
    },
    AlertTab : { 
        screen: AlertTab
    }
}, TabNavigatorConfig);

export default const AppNavigator = StackNavigator({
    App: {
        screen: TabView
    }
})

あとがき

タブの標準の動作を変更すること自体、ユーザービリティを低下させそうなので、使いどころは考えた方がいいかも

参考リンク

https://github.com/react-community/react-navigation/issues/314