react-native-dropdown-picker onChange handler

2.7k Views Asked by At

I am developing an app in React Native Expo which is supposed to work both on mobile devices and on the web. I have a problem with abovementioned library

How should I trigger an action on change of selection in react-native-dropdown-picker? There are only props like

  open,
  setOpen,
  value,
  setValue,
  items,
  setItems,

open/setOpen is a boolean only to track open state, items/setItems is an array of objects of expected by dropdown shape, so only setValue seem to be the one that can do the job. Value however is a function with always empty name field and I don't know how and if I can use it to handle any actions, only useEffect react to the change of value state variable. The thing is that it should not be happening in useEffect I think, but in event handler, and I have issues on mobile devices (both on web and in the mobile app). This compoennt is for React Native, but strangely it works on dektops like a charm and not in mobile apps and on mobile devices. Clearly I am doing something wrong, I just don't know what. This is the component code

import React from "react";
import { Platform, StyleSheet, View } from "react-native";
import DropDownPicker from "react-native-dropdown-picker";
import { FONTS, COLORS } from "../../constants/ui";

interface Props {
  open: boolean;
  value: string;
  items: any[];
  setOpen: React.Dispatch<any>;
  setValue: React.Dispatch<any>;
  setItems: React.Dispatch<any>;
}

export const PlatformDropdown: React.FC<Props> = ({
  open,
  setOpen,
  value,
  setValue,
  items,
  setItems,
}) => {
  return Platform.OS === "android" ? (
    <View style={[open && styles.dropdownCanvas]}>
      <DropDownPicker
        open={open}
        value={value}
        items={items}
        setOpen={setOpen}
        setValue={setValue}
        setItems={setItems}
        placeholder={`Rating`}
        showTickIcon={false}
        style={styles.dropdown}
        containerStyle={styles.dropdownContainerStyle}
        placeholderStyle={styles.dropdownPlaceholderStyle}
        dropDownContainerStyle={styles.dropDownContainerStyle}
        listItemLabelStyle={styles.dropdownListItemLabelStyle}
        selectedItemContainerStyle={styles.dropdownSelectedItemContainerStyle}
        zIndex={30}
      />
    </View>
  ) : (
    <DropDownPicker
      open={open}
      value={value}
      items={items}
      setOpen={setOpen}
      setValue={setValue}
      setItems={setItems}
      placeholder={`Rating`}
      showTickIcon={false}
      style={styles.dropdown}
      containerStyle={styles.dropdownContainerStyle}
      placeholderStyle={styles.dropdownPlaceholderStyle}
      dropDownContainerStyle={styles.dropDownContainerStyle}
      listItemLabelStyle={styles.dropdownListItemLabelStyle}
      selectedItemContainerStyle={styles.dropdownSelectedItemContainerStyle}
      zIndex={30}
    />
  );
};

const styles = StyleSheet.create({
  dropdown: {
    flexDirection: "row",
    padding: 10,
    maxWidth: "100%",
    backgroundColor: COLORS.greys["gray-300"],
    borderRadius: 7,
    marginVertical: 7,
  },
  dropdownContainerStyle: { borderColor: COLORS.greys["gray-400"] },
  dropdownPlaceholderStyle: {
    color: COLORS.FONT_COLOR,
    fontWeight: "bold",
  },
  dropDownContainerStyle: {
    backgroundColor: COLORS.greys["gray-100"],
    padding: 5,
    borderColor: COLORS.greys["gray-400"],
  },
  dropdownListItemLabelStyle: {
    color: COLORS.FONT_COLOR,
    padding: 10,
    fontFamily: FONTS.text,
  },
  dropdownSelectedItemContainerStyle: {
    backgroundColor: COLORS.greys["gray-300"],
    borderRadius: 3,
  },
  dropdownCanvas: { minHeight: 190 },
});

and this is useEffect responsible for managing actions on dropdown selection

  useEffect(() => {
    setLabs([]);
    switch (value) {
      case "rating":
        sortBy("rating", "desc");
        break;
      case "price":
        console.log(labs);
        const byPrice = labs.sort((a, b) => {
          const testIdx = a.tests.findIndex(({ title }) => title === testName);
          return a.tests[testIdx].price - b.tests[testIdx].price;
        });
        sortTimeoutRef = setTimeout(() => setLabs([...byPrice]), 200);
        break;
      case "distance":
        sortByDistance();
        break;
      default:
        sortBy("rating", "desc");
        break;
    }
    return () => {
      clearTimeout(sortTimeoutRef);
    };
  }, [value]);

Thanks a lot for any advice.

1

There are 1 best solutions below

0
On

There are more props than you have listed.

The prop that provides what you need, is probably onChangeValue.

For the complete list of props, that are available, you can check out the documentation