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
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.
keyboardShouldPersistTaps should be "handled" if you want it to work on first tap.