skip to Main Content

I have a react native modal with a search bar and a flatlist that shows results. The search result in the flatlist has to be tapped twice for the click to register. I need to figure out how to make it work on first click. Here is the code

const Item = ({ item, onPress, value }) => (
  <TouchableOpacity style={styles.modalItemStyle} onPress={onPress}>
    <View style={styles.modalIconStyle}>
      {item.id === value && <Icon name="sheep" size={20} color="#68c25a" />}
    </View>
    <Text style={styles.modalItemTextStyle}>{item.title}</Text>
  </TouchableOpacity>
);

const MyDropdown = ({
  data,
  label,
  field,
  onSelect,
  value,
  searchable = true,
}) => {
  const [modalOpen, setModalOpen] = useState(false);
  const [selectedValue, setSelectedValue] = useState(value);
  const [query, setQuery] = useState("");
  const [modalData, setModalData] = useState(data);


  useEffect(() => {
    if (query.length > 0) {
      const filteredData = data.filter((item) =>
        item.title.toLowerCase().includes(query.toLowerCase())
      );
      setModalData(filteredData);
    } else {
      setModalData(data);
    }
  }, [query]);

  const inputRef = useRef(null);
  const searchRef = useRef(null);

  const renderItem = ({ item }) => {
    return (
      <Item
        item={item}
        value={selectedValue.id}
        onPress={() => {
          inputRef.current.blur();
          Keyboard.dismiss();
          setQuery("");
          setSelectedValue(item);
          setModalOpen(false);
        }}
      />
    );
  };

  return (
    <View style={styles.selectContainer}>
      <TextInput
        ref={inputRef}
        //react native paper text input with value and label
        label={label}
        value={selectedValue.title}
        style={styles.sheepTextInput}
        mode="outlined"
        onChangeText={(text) => onSelect(text)}
        showSoftInputOnFocus={false}
        onFocus={() => {
          setModalOpen(true);
          inputRef.current.blur();
        }}
      ></TextInput>
      <Modal height="auto" isVisible={modalOpen}>
        <View style={styles.modal}>
          {searchable && (
            <View>
              <TextInput
                ref={searchRef}
                mode="outlined"
                outlineColor="#68c25a"
                activeOutlineColor="#68c25a"
                style={styles.modalSearch}
                value={query}
                onChangeText={(q) => setQuery(q)}
                placeholder="Search"
                //add clear button
                right={
                  <TextInput.Icon
                    name="close"
                    color="#68c25a"
                    onPress={() => {
                      setQuery("");
                    }}
                  />
                }
              ></TextInput>
            </View>
          )}
          <FlatList
            keyboardShouldPersistTaps="always"
            data={modalData}
            renderItem={renderItem}
            keyExtractor={(item) => item.id}
          />
        </View>
      </Modal>
    </View>
  );
};

I tried adding keyboardShouldPersistTaps with different options to flatlist, I also tried to blur through refs (searchref), but none of those approaches worked. What am I doing wrong?

2

Answers


  1. Chosen as BEST ANSWER

    I managed to fix this by setting the keyboardshouldpersisttaps property to handled on every scrollview, including the flatlist in question and the component that renders all of those inputs in my form. I also had to wrap the flatlist with the search input in a scrollview. Of course I now have a virtualized lists should never be nested warning, but at least the taps now work.


  2. keyboardShouldPersistTaps should be "handled" if you want it to work on first tap.

    <FlatList
       keyboardShouldPersistTaps="handled"
       data={modalData}
       renderItem={renderItem}
       keyExtractor={(item) => item.id}
      />
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search