react-native-multi-selectbox
react-native-multi-selectbox copied to clipboard
Can't use inside a ScrollViews
Got this error when I used this inside a ScrollView
VirtualizedLists should never be nested inside plain ScrollViews with the same orientation because it can break windowing and other functionality - use another VirtualizedList-backed container instead.
@sankaSanjeeva Did you find any solution to this problem?
No, I created my own code.
Can you please share it with me?
make sure to import style
import React, { useState } from "react";
import { ScrollView, Modal, Text, Pressable, View, TouchableOpacity, Image } from "react-native";
import PropTypes from 'prop-types';
import { Dimensions } from 'react-native';
import styles from '../../Assets/styles/common/multiPicker'
const MultiPicker = ({ items, placeholder, icon, selectedItems, onChangeItems }) => {
const [visible, setVisible] = useState(false);
const [selected, setSelected] = useState(selectedItems);
const windowHeight = Dimensions.get('window').height;
function selectItems(id) {
if (selected?.includes(id)) {
setSelected(selected.filter(x => x != id));
} else {
setSelected([...selected, id]);
}
}
function closeModel() {
onChangeItems(selected);
setVisible(false);
}
return (
<View>
<View>
<Pressable
style={styles.inputArea}
onPress={() => setVisible(true)
}>
{icon && (
<View style={styles.iconContainer}>
<Image source={icon} />
</View>
)}
<Text style={{ paddingLeft: icon ? 0 : 15 }}>{placeholder}</Text>
</Pressable>
{
selected?.length > 0 && <View style={styles.previewContainer}>
{selected?.map((id, index) => (
<View key={index} style={styles.previewItem}>
<Text>{items?.find(x => x.id == id).name}</Text>
<TouchableOpacity onPress={() => {
setSelected(selected.filter(x => x != id));
onChangeItems(selected.filter(x => x != id));
}}>
<Image style={styles.closeIcon} source={require('../../Assets/Images/close.png')} />
</TouchableOpacity>
</View>
))}
</View>
}
</View>
<Modal
animationType="fade"
transparent={true}
visible={visible}
onRequestClose={() => {
console.log("Modal has been closed.");
setVisible(!visible);
}}
>
<View style={styles.centeredView}>
<View style={styles.mainContainer}>
<View style={styles.itemsContainer}>
<ScrollView style={{ maxHeight: (windowHeight - 200) }}>
{
items?.length == 0 ? (
<Text style={{ textAlign: 'center' }}>No items to select</Text>
) : (
items?.map((item, index) => (
<View
key={index}
style={styles.itemContainer}
>
<TouchableOpacity onPress={() => selectItems(item?.id)} >
<Text
style={selected?.includes(item.id) ? { color: '#000' } : { color: '#bbb' }}
>
{item.name}
</Text>
</TouchableOpacity>
</View>
))
)
}
</ScrollView>
</View>
<Pressable
style={styles.btnAction}
onPress={() => closeModel()}
>
<Text>{items?.length == 0 ? 'Close' : 'Done'}</Text>
</Pressable>
</View>
</View>
</Modal>
</View>
)
}
MultiPicker.propTypes = {
items: PropTypes.array,
placeholder: PropTypes.string,
selectedItems: PropTypes.array,
onChangeItems: PropTypes.func
}
MultiPicker.defaultProps = {
items: [],
placeholder: 'Select',
selectedItems: []
}
export default MultiPicker;
style file
import { StyleSheet } from "react-native";
export default StyleSheet.create({
btnAction: {
width: 200,
height: 50,
borderRadius: 4,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#f9d132'
},
closeIcon: {
width: 12,
height: 12,
marginLeft: 10,
},
centeredView: {
flex: 1,
justifyContent: "center",
alignItems: "center"
},
iconContainer: {
width: 55,
alignItems: 'center'
},
inputArea: {
flexDirection: 'row',
alignItems: 'center',
paddingRight: 15,
paddingVertical: 15,
backgroundColor: '#ffffff',
borderColor: '#f0f0f0',
borderWidth: 1,
borderRadius: 4,
elevation: 5,
shadowColor: '#000',
shadowOffset: {
width: 0,
height: 2
},
shadowOpacity: 0.25,
shadowRadius: 4
},
itemContainer: {
padding: 15,
borderBottomColor: '#bbb',
borderBottomWidth: 1
},
itemsContainer: {
marginBottom: 20,
width: '100%'
},
mainContainer: {
backgroundColor: '#ffffff',
width: '90%',
borderRadius: 5,
padding: 16,
alignItems: "center",
shadowColor: '#000',
shadowOffset: {
width: 0,
height: 2
},
shadowOpacity: 0.25,
shadowRadius: 4,
elevation: 5
},
previewContainer: {
flexDirection: 'row',
flexWrap: 'wrap'
},
previewItem: {
flexDirection: 'row',
alignItems: 'center',
padding: 10,
marginTop: 16,
marginHorizontal: 8,
borderRadius: 20,
borderColor: '#666',
borderWidth: 1
}
});
Thank you so much. I will try this out!!
and use it with or without an icon
import React, { useState } from 'react';
import MultiPicker from '../../Common/MultiPicker';
const [selectedHorses, setSelectedHorses] = useState([]);
<MultiPicker
items={allHorses} // arra => [{id: '1', name: 'Apple'}, ...]
placeholder='Select Horses'
icon={require('../../../Assets/Images/horse-db.png')}
selectedItems={selectedHorses} //
onChangeItems={setSelectedHorses}
/>
i get same issue
@hungdev You can either go for the solution shared by @sankaSanjeeva and create a separate component. Or there is also a work around that you can use.
<ScrollView nestedScrollEnabled = {true}> <SelectBox listOptionProps={{ nestedScrollEnabled: true }}/> </ScrollView>
This will show you the warning for Virtualized lists but the functionality won't be affected and you will be able to scroll through the list.
nestedScrollEnabled
works only for Android(https://reactnative.dev/docs/scrollview#nestedscrollenabled-android), How to fix this issue on IOS?
@hungdev You can either go for the solution shared by @sankaSanjeeva and create a separate component. Or there is also a work around that you can use.
<ScrollView nestedScrollEnabled = {true}> <SelectBox listOptionProps={{ nestedScrollEnabled: true }}/> </ScrollView>
This will show you the warning for Virtualized lists but the functionality won't be affected and you will be able to scroll through the list.
work for me with temporary solution in android
import { LogBox } from 'react-native'
useEffect(() => {
LogBox.ignoreLogs(["VirtualizedLists should never be nested"]);
...
<ScrollView nestedScrollEnabled = {true}> <SelectBox listOptionProps={{ nestedScrollEnabled: true }}/> </ScrollView>
note: popup ui notif error hidding, function scroll work, but still show error in console. thanks, i hope get permanent fix for this issue with update version react-native-multi-selectbox.