每当我切换标签时,如何将下拉状态设置为初始状态?

How to set the dropdown state to initial whenever I switch Tabs?

我有一个带有三个屏幕的 bottomtabbar,所有屏幕在 header 处都有一个下拉选择器。 每当我打开下拉菜单并更改选项卡屏幕时,我的下拉菜单仍保持打开状态,但是我希望我的下拉菜单在更改选项卡时最初保持关闭状态。 我的具体代码如下:

import React, {useEffect, useState} from 'react';
import {ActivityIndicator} from 'react-native';

import {SafeAreaView, View, Image, TouchableOpacity} from 'react-native';
import MaterialCommunityIcons from 'react-native-vector-icons/MaterialCommunityIcons';
import MaterialIcon from 'react-native-vector-icons/MaterialIcons';
import FontAwesomeIcon from 'react-native-vector-icons/FontAwesome';
// bottom tab
import {createBottomTabNavigator} from '@react-navigation/bottom-tabs';
import Icon from 'react-native-vector-icons/FontAwesome';
import DropDownPicker from 'react-native-dropdown-picker';
//tabs component
import HomeTabScreen from './HomeTabScreen';
import ConsultationHomeScreen from '../Consult/ConsultationHomeScreen';
import PlansTabScreen from './PlansTabScreen';
import ChatTabScreen from './ChatTabScreen';
import {useSelector, useDispatch} from 'react-redux';
import {
  setSelectedChild,
  setSelectedChildId,
} from '../../store/actions/userActions';
import {isValidObject} from '../../utils/baseUtils';
import {getChildFromUserChildrenList} from '../../utils/userUtils';
import {setAppReload} from '../../store/actions/HomeActions';

export default function PLHomeScreen(props) {
  const {navigation} = props;
  const [loading, setLoading] = useState(false);

  const Tab = createBottomTabNavigator();
  //child related
  const [loadApi, setLoadApi] = useState(true);

  //Use for all the dispatch actions
  const dispatch = useDispatch();

  const User = useSelector((state) => state.userReducer.user);
  const mSChildId = useSelector((state) => state.userReducer.selectedChildId);
  let mChild = getChildFromUserChildrenList(User, mSChildId);
  const defaultchildvalue = getChildFromUserChildrenList(User, mSChildId);
  const reloadApp = useSelector(
    (state) => state.premiumCardActionTypesReducer.reloadApp,
  );

  console.log('!!!! Reload App !!!!', reloadApp);

  useEffect(() => {
    if (!isValidObject(mChild)) {
      if (!isValidObject(mSChildId)) {
        let cid = User.children[0].id;
        handleChangeChild(cid);
      }
    }
    if (loadApi == true) {
      setLoadApi(false);
      setLoading(false);
    }
    if (reloadApp == true) {
      setLoadApi(true);
      setLoading(true);
      dispatch(setAppReload(false));
    }
    console.log('!!!! Reload App !!!!', reloadApp);
  }, [User, mSChildId, loadApi, reloadApp]);

  const handleChangeChild = (id) => {
    dispatch(setSelectedChildId(id));
    mChild = getChildFromUserChildrenList(User, id);
    setLoadApi(true);
    setLoading(true);
  };

  return (
    <SafeAreaView
      style={{
        flex: 1,
        alignItems: 'stretch',
        justifyContent: 'center',
        backgroundColor: '#FE017E',
      }}>

      <View>
        <View
          style={{
            height: 56,
            backgroundColor: '#FE017E',
            alignItems: 'center',
            flexDirection: 'row',
            justifyContent: 'space-between',
          }}>
          <TouchableOpacity
            onPress={() => navigation.openDrawer()}
            style={{
              backgroundColor: '#FE017E',
              width: '100%',
              height: 40,
              padding: 10,
            }}
            underlayColor="transparent">
            <Icon size={20} name="bars" style={{marginLeft: 2}} color="#fff" />
          </TouchableOpacity>
        </View>
        {User != null &&
          User.children != undefined &&
          User.children != null &&
          User.children.length > 0 &&
          mChild &&
          mChild != undefined &&
          mChild != null && (
            <DropDownPicker
              items={User.children.map((item) => {
                return {
                  label: item.name + '\n' + item.dob_text,
                  value: item,
                  icon: () =>
                    item.pic_url ? (
                      <Image
                        source={{
                          uri: item.pic_url,
                        }}
                        style={{height: 30, width: 30, borderRadius: 15}}
                      />
                    ) : item.gender === 'male' ? (
                      <Image
                        source={{
                          uri:
                            'https://cdn3.iconfinder.com/data/icons/materia-human/24/013_042_newborn_infant_child_baby-512.png',
                        }}
                        style={{height: 30, width: 30}}
                      />
                    ) : (
                      <Image
                        source={{
                          uri:
                            'https://cdn3.iconfinder.com/data/icons/materia-human/24/013_042_newborn_infant_child_baby-512.png',
                        }}
                        style={{height: 30, width: 30}}
                      />
                    ),
                };
              })}
              onChangeItem={(item) => {
                if (item.value.id != mSChildId) {
                  handleChangeChild(item.value.id);
                }
              }}
              containerStyle={{
                marginLeft: 60,
                marginTop: -46,
                marginBottom: 10,
                height: 40,
              }}
              defaultValue={defaultchildvalue}
              dropDownStyle={{
                backgroundColor: '#ffffff',
                marginLeft: 40,
                borderColor: 'grey',
                borderWidth: 1,
                borderBottomEndRadius: 0,
                borderBottomLeftRadius: 0,
                borderBottomStartRadius: 0,
                borderBottomRightRadius: 0,
                minWidth: 100,
                maxWidth: 150,
              }}
              itemStyle={{
                justifyContent: 'flex-start',
                fontWeight: 'bold',
                fontSize: 20,
                borderColor: '#FE017E',
              }}
              style={{
                backgroundColor: '#FE017E',
                borderBottomEndRadius: 0,
                borderBottomLeftRadius: 0,
                borderBottomRightRadius: 0,
                borderBottomStartRadius: 0,
                borderTopEndRadius: 0,
                borderTopLeftRadius: 0,
                borderRadius: 0,
                borderColor: '#FE017E',
                minWidth: 100,
                maxWidth: 150,
              }}
              labelStyle={{
                marginLeft: 15,
                fontWeight: 'bold',
                fontSize: 10,
                color: 'black',
                textAlign: 'center',
              }}
              arrowColor={'white'}
              activeLabelStyle={{color: '#FE017E'}}
              selectedLabelStyle={{color: 'white'}}
            />
          )}
      </View>

      {loading ? (
        <ActivityIndicator
          color="#FF1493"
          size="large"
          style={{
            backgroundColor: 'white',
            justifyContent: 'center',
            alignItems: 'center',
            flex: 1,
            flexDirection: 'row',
          }}
        />
      ) : (
        // <View>
        <Tab.Navigator
          lazy={true}
          initialRouteName="Home"
          tabBarOptions={{
            labelStyle: {
              color: '#FF1493',
              fontSize: 12,
            },
          }}>
          <Tab.Screen
            name="Home"
            // uncommnet below line to see new Home Tab
            component={HomeTabScreen}
            // uncomment below see old Home Tab
            // component={HomeScreen}
            options={{
              tabBarLabel: 'Home',
              tabBarIcon: ({}) => (
                <MaterialIcon name="home" color="#FF1493" size={30} />
              ),
            }}
          />
          <Tab.Screen
            name="Consult"
            component={ConsultationHomeScreen}
            initialParams={{
              mSChildId: mSChildId,
            }}
            options={{
              tabBarLabel: 'Consult',
              tabBarIcon: ({}) => (
                <FontAwesomeIcon name="stethoscope" color="#FF1493" size={30} />
              ),
            }}
          />
          {mChild != null && mChild.is_sc_subscribed == true ? (
            <Tab.Screen
              name="Chat"
              component={ChatTabScreen}
              options={{
                tabBarLabel: 'Chat',
                tabBarIcon: ({}) => (
                  <MaterialCommunityIcons
                    name="chat-outline"
                    color="#FF1493"
                    size={30}
                  />
                ),
              }}
            />
          ) : (
            <Tab.Screen
              name="Plans"
              component={PlansTabScreen}
              options={{
                tabBarLabel: 'Plans',
                tabBarIcon: ({}) => (
                  <MaterialCommunityIcons
                    name="crown-outline"
                    color="#FF1493"
                    size={30}
                  />
                ),
              }}
            />
          )}
        </Tab.Navigator>
      )}
    </SafeAreaView>
  );
}

请告诉我如何在切换标签时让下拉菜单保持关闭状态。 任何线索将不胜感激。

为您的下拉选择器定义一个控制器,然后将自定义按钮添加到您的选项卡导航器。自定义按钮将允许您实现一个 onPress 侦听器,并且在侦听器中您可以 运行 controller.close() 关闭下拉选择器。

如果您不熟悉下拉选择器的控制器,您可以查看 the npm page

编辑:以下是根据 npm 页面设置控制器的方法:

const [value, setValue] = useState(null);
const [items, setItems] = useState([ {...}, ... ]);
let controller;

<DropDownPicker
    items={items}
    controller={instance => controller = instance}
    onChangeList={(items, callback) => {
        new Promise((resolve, reject) => resolve(setItems(items)))
            .then(() => callback())
            .catch(() => {});
    }}

    defaultValue={value}
    onChangeItem={item => setValue(item.value)}
/>

然后您可以在代码中的任意位置使用控制器。