【问题标题】:How to render a Modal within a Tab Screen in React Navigation如何在 React Navigation 中的选项卡屏幕中呈现模态
【发布时间】:2020-09-11 02:00:49
【问题描述】:

当用户按下中间按钮时,我需要呈现一个模式。我正在使用react-native-raw-bottom-sheet 库为我的应用程序提供模态。 我试图在 内传递一个道具isFocused={props.navigation.isFocused},但问题是当我将道具传递给 based if is or not focus in the 时,会渲染两次而不是一次。

我也试过直接触发模态但没有成功。

我的问题是,当用户按下时,我需要渲染新的,它将包含模态中内容的空洞逻辑,并且还将呈现模态。

我的 tab.routes.js

import React from 'react';
import {createBottomTabNavigator} from '@react-navigation/bottom-tabs';
import TabButton from '../components/Tab/Button';
import Icon from 'react-native-vector-icons/MaterialIcons';

import Home from '../containers/Home';
import Adjustment from '../containers/Adjustment';
import Graphic from '../containers/Graphic';
import Help from '../containers/Help';
import NewTransaction from '../containers/NewTransaction';

const icons = {
  Home: {
    name: 'home',
  },
  Graphic: {
    name: 'pie-chart',
  },
  NewTransaction: {
    name: 'notifications-none',
  },
  Help: {
    name: 'help-outline',
  },
  Adjustment: {
    name: 'settings',
  },
};

const Tab = createBottomTabNavigator();

const TabRoutes = () => (
  <Tab.Navigator
    initialRouteName="HomeScreen"
    screenOptions={({route, navigation}) => ({
      tabBarIcon: ({color, size, focused}) => {
        if (route.name === 'NewTransaction') {
          return <TabButton focused={focused} onPress={() => navigation.navigate('NewTransaction')} />;
        }
        const {name} = icons[route.name];
        return <Icon name={name} size={size} color={color} />;
      },
    })}
    tabBarOptions={{
      keyboardHidesTabBar: true,
      activeTintColor: '#f8b006',
      inactiveTintColor: '#1C3041',
      style: {
        height: 60,
      },
      iconStyle: {
        marginTop: 5,
      },
      labelStyle: {
        fontSize: 12,
        marginBottom: 10,
      },
    }}>
    <Tab.Screen
      options={{
        title: 'Home',
      }}
      name="Home"
      component={Home}
    />
    <Tab.Screen
      options={{
        title: 'Gráfico',
      }}
      name="Graphic"
      component={Graphic}
    />
    <Tab.Screen
      options={{
        title: '',
      }}
      name="NewTransaction"
      component={NewTransaction}
    />
    <Tab.Screen
      options={{
        title: 'Ajuda',
      }}
      name="Help"
      component={Help}
    />
    <Tab.Screen
      options={{
        title: 'Ajustes',
      }}
      name="Adjustment">
      {(props) => (
        <Adjustment isVisible={props.navigation.isFocused()} onPress={() => props.navigation.navigate('Home')} />
      )}
    </Tab.Screen>
  </Tab.Navigator>
);

export default TabRoutes;

选项卡/按钮/index.js

import React from 'react';
import {TouchableWithoutFeedback} from 'react-native-gesture-handler';
import Icon from 'react-native-vector-icons/MaterialIcons';
import Button from './styles';

const TabButton = ({onPress, focused}) => {
  return (
    <TouchableWithoutFeedback onPress={onPress}>
      <Button focused={focused}>
        <Icon name="add" size={35} color={'white'} />
      </Button>
    </TouchableWithoutFeedback>
  );
};

export default TabButton;

以及将显示模态内容的组件

import React from 'react';
import {Text, View} from 'react-native';
const NewTransaction = ({isVisible}) => {
  return (
    <View>
      <Text>Welcome to NewTransactions </Text>
    </View>
  );
};

export default NewTransaction;

【问题讨论】:

    标签: react-native react-navigation react-navigation-bottom-tab


    【解决方案1】:

    这是我的主页标签,在你看来是这样的

    我用代码自定义标签栏,但添加按钮不是屏幕,它只是一个按钮和弹出选项供选择

    import {hideModalCreate, showModalCreate} from '@features/loading/actions';
    import CreateYCTV from '@features/main/CreateYCTV';
    import HomeScreen from '@features/main/Home';
    import Manager from '@features/main/Manager';
    import Notification from '@features/main/Notification';
    import {createBottomTabNavigator} from '@react-navigation/bottom-tabs';
    import images from '@res/icons';
    import * as React from 'react';
    import {Image, Pressable, View} from 'react-native';
    import {Text, useTheme} from 'react-native-paper';
    import {useSafeAreaInsets} from 'react-native-safe-area-context';
    import {connect} from 'react-redux';
    import ProductStack from './ProductStack';
    
    const Tab = createBottomTabNavigator();
    
    function MyTabBar({
      state,
      descriptors,
      navigation,
      showModalCreate,
      hideModalCreate,
      isShowModalCreate,
    }) {
      const {colors} = useTheme();
      const insets = useSafeAreaInsets();
    
      const focusedOptions = descriptors[state.routes[state.index].key].options;
    
      if (focusedOptions.tabBarVisible === false) {
        return null;
      }
    
      return (
        <View
          style={{
            flexDirection: 'row',
            backgroundColor: '#FFFFFF',
            paddingBottom: Math.max(insets.bottom, 0),
          }}>
          {state.routes.map((route, index) => {
            const {options} = descriptors[route.key];
            const label =
              options.tabBarLabel !== undefined
                ? options.tabBarLabel
                : options.title !== undefined
                ? options.title
                : route.name;
    
            const isFocused = state.index === index;
    
            const getSourceImage = (isFocused) => {
              switch (route.name) {
                case 'home':
                  return isFocused ? images.tab_home1 : images.tab_home;
                case 'loans':
                  return isFocused ? images.tab_searching1 : images.tab_searching;
                case 'notification':
                  return isFocused ? images.notifications1 : images.notifications;
                case 'manager':
                  return isFocused
                    ? images.tab_paper_folder1
                    : images.tab_paper_folder;
                default:
                  return images.tab_add;
              }
            };
    
            const onPress = () => {
              if (route.name === 'create') {
                if (isShowModalCreate) {
                  hideModalCreate();
                  return;
                }
                showModalCreate();
                return;
              }
              hideModalCreate();
              const event = navigation.emit({
                type: 'tabPress',
                target: route.key,
                canPreventDefault: true,
              });
    
              if (!isFocused && !event.defaultPrevented) {
                navigation.navigate(route.name);
              }
            };
    
            const onLongPress = () => {
              navigation.emit({
                type: 'tabLongPress',
                target: route.key,
              });
            };
    
            return (
              <Pressable
                accessibilityRole="button"
                accessibilityStates={isFocused ? ['selected'] : []}
                accessibilityLabel={options.tabBarAccessibilityLabel}
                testID={options.tabBarTestID}
                onPress={onPress}
                onLongPress={onLongPress}
                style={{
                  flex: 1,
                  alignItems: 'center',
                  justifyContent: 'center',
                  paddingVertical: 8,
                  backgroundColor: 'white',
                }}>
                <Image source={getSourceImage(isFocused)} />
                {route.name != 'create' ? (
                  <Text
                    style={{
                      color: isFocused ? colors.primary : colors.placeholder,
                      fontSize: 10,
                      marginTop: 4,
                    }}>
                    {label}
                  </Text>
                ) : null}
              </Pressable>
            );
          })}
        </View>
      );
    }
    
    const Tabbar = ({showModalCreate, hideModalCreate, isShowModalCreate}) => {
      return (
        <Tab.Navigator
          tabBar={(props) => (
            <MyTabBar
              isShowModalCreate={isShowModalCreate}
              showModalCreate={showModalCreate}
              {...props}
              hideModalCreate={hideModalCreate}
            />
          )}>
          <Tab.Screen
            name="home"
            component={HomeScreen}
            options={{
              title: 'Trang chủ',
            }}
          />
          <Tab.Screen
            name="loans"
            component={ProductStack}
            options={{
              title: 'Sản phẩm',
            }}
          />
          <Tab.Screen name="create" component={CreateYCTV} />
          <Tab.Screen
            name="notification"
            component={Notification}
            options={{
              title: 'Thông báo',
              tabBarBadge: '13',
            }}
          />
          <Tab.Screen
            name="manager"
            component={Manager}
            options={{
              title: 'Quản lý',
            }}
          />
        </Tab.Navigator>
      );
    };
    
    const mapStateToProps = (state, ownProps) => {
      return {
        isShowModalCreate: state.loading.isShowModalCreate,
      };
    };
    
    const mapDispatch = {
      showModalCreate: showModalCreate,
      hideModalCreate: hideModalCreate,
    };
    
    export default connect(mapStateToProps, mapDispatch)(Tabbar);
    
    

    【讨论】:

    • 你能分享更多我对 showmodalCreate 和 hideModalCreate 感到困惑的代码
    • 这两个函数只是在 redux 中改变状态 isShowModalCreate
    • 这对我来说不是好方法,我认为有一个状态可以获取最后一个视图并且您的模态位于根组件中
    猜你喜欢
    • 2020-06-20
    • 2017-11-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-06-26
    • 2019-01-23
    相关资源
    最近更新 更多