React Native Base Picker displaying Warning : VirtualizedLists should never be nested inside plain ScrollViews - react-native

I'm using Native base's Picker component and rendering using .map:
Tried everything the Internet has suggested!! Didn't get it fixed yet
<Item rounded style={{marginBottom:20}}>
<Picker selectedValue={this.state.district} onValueChange={(val)=>this.setDistrict(val)}>
<Picker.Item label='Select District' value='0'/>
{this.state.districtsList.map((item,index) => {
return (<Picker.Item label={item.name} value={item.id} key={index+1}/>) //if you have a bunch of keys value pair
})}
</Picker>

Experiencing the same thing!
You can use like this:
<SafeAreaView> Your code block </SafeAreaView>

Related

Is there a FlatList-like View without the scrolling?

Basically, I have a list of items (with images) inside a single Card (custom component). Because the rendering of those items is slow, I wanted to use a FlatList to render them incrementally.
Unfortunately, I get the expected error
VirtualizedLists should never be nested inside plain ScrollViews ...
But I don't actually want to use a ScrollView inside the Card. I just want to render a few Items in a single Card, which should change its size to fit all the items.
Setting scrollEnabled={false} on the FlatList still shows the error above.
Using the ListHeaderComponent and ListFooterComponent props is not an option, because the content above and below should NOT be rendered inside the Card.
Here is a minimal example of what I mean:
const Comp = () => {
return (
<ScrollView contentInsetAdjustmentBehavior="automatic">
<Text>Header</Text>
<Card>
<FlatList
data={data}
renderItem={({ item }) => (
<Image source={{uri: item.localImageUrl}}/>
)}
keyExtractor={(item) => item.id}
scrollEnabled={false}
initialNumToRender={0}
maxToRenderPerBatch={3}
contentInsetAdjustmentBehavior='automatic'
/>
</Card>
<Text>Footer</Text>
</ScrollView>
);
};
What's interesting though, that aside from the error - I get the result I expected, and I could technically hide that error and ignore it, but that does not seem like the recommended approach.
Important: I am not specifically looking for a FlatList solution. It could technically be any Component that renders items incrementally in a non-blocking way.
The important point with a Flatlist is the reusing of cells so that not all components need to be rendered at the same time. So scrolling is an important part of this. On the other hand two scrollable components inside eachother will make it impossible for the system to know which component should be scrolled.
If there are only 3 items and it should not be scrollable you can just include a list of items inside the Scrollview like this:
const Comp = () => {
return (
<ScrollView contentInsetAdjustmentBehavior="automatic">
<Text>Header</Text>
<Card>
{ data.map((item, index) => {
return (
<Text key={index}>{item.title}</Text>
);
}) }
</Card>
<Text>Footer</Text>
</ScrollView>
);
};

VirtualizedLists should never be nested inside plain ScrollViews by using react native SearchableDropdown

How to use scrollview over package like react-native-autocomplete-input? Basically I have a form in my react native package in which there are multiple input fields including autocomplete so I need a scroll over my screen so how should I achieve that?My code looks like that
<ScrollView>
<Card>
<TextInput />
<SearchableDropdown />
<TextInput />
<Picker />
</Card>
</Scrollview>
It gives me that error
VirtualizedLists should never be nested inside plain ScrollViews with the same orientation because it can break windowing and other functionality

Is there a any way to get the text value of the TextInput using ref in react native?

I am getting the text of the TextInput using onChangeText event and state.
<View style={styles.inputContainerStyle}>
<TextInput
autoFoucs={true}
ref={inputRef}
style={styles.textInputStyle}
placeholder="type here ..."
placeholderTextColor='#838389'
multiline
underlineColorAndroid="transparent"
onChangeText={text => handleTextChange(text)}
value={selectedText}
/>
<TouchableOpacity style={styles.submitBtnWrapperStyle} onPress={() => handleMsgSend()}>
<Icon name={msgEditMode ? "check" : "paper-plane"} size={20} color="#ffffff" />
</TouchableOpacity>
</View>
...
// handle text change on textinput
const handleTextChange = text => {
channel && channel.typing();
setSelectedText(text);
}
But actually whenever text is changed, the render function also is called because of changing state value and it is making the whole screen more slow.
So I am looking for the alternative way to get the text not using onChangeText event.
Is there any native way to get the text using ref?
I hope kind help.
thanks...
Yes, you can access the value of text input using ref like this
this.inputRef._lastNativeText

How to fix this warning: VirtualizedLists should never be nested inside plain ScrollViews with the same orientation

When I use FlatList component inside ScrollView I see a warning:
VirtualizedLists should never be nested inside plain ScrollViews with the same orientation - use another VirtualizedList-backed container instead.
Before and after FlatList I use a lot of other components and my screen is long.
I tried to wrap content with SafeAreaView and it doesn't help me, because in this case I can't scroll the content. I also tried to use ListHeaderComponent={SafeAreaView} and ListFooterComponent={SafeAreaView} in <FlatList>.
I use:
"react": "16.9.0",
"react-native": "0.61.5",
Here is a VirutalizedList -backed container implementation using FlatList:
import React from 'react';
import { FlatList } from 'react-native';
export default function VirtualizedView(props: any) {
return (
<FlatList
data={[]}
ListEmptyComponent={null}
keyExtractor={() => "dummy"}
renderItem={null}
ListHeaderComponent={() => (
<React.Fragment>{props.children}</React.Fragment>
)}
/>
);
}
Usage:
<VirtualizedView>
<Text>Anything goes here, even FlatList works good</Text>
<View style={{minHeight: 480}}> // leave enough space for better user experience
<FlatList
data={data}
keyExtractor={keyExtractor}
renderItem={({item}) => <Item data={item} />}
onRefresh={refetch}
refreshing={loading}
onEndReached={concatData}
/>
</View>
</VirtualizedView>
This will show scrollbar when your screen is too long and also remove the pesky warning message and performance will be saved without any problem.
There is a simpler solution using https://facebook.github.io/react-native/docs/scrollview#nestedscrollenabled
This is only required for Android (iOS works as expected even without it).
Just make sure to enable this prop in both parent and child ScrollViews (or child FlatLists).
What I've done in my case is something along the lines of this:
render() {
return (
<SafeAreaView style={{ flex: 1 }}>
...
<ScrollView>
...
<FlatList
scrollEnabled={false} // this line is important
...
</FlatList>
...
</ScrollView>
</SafeAreaView>
);
}
It doesn't remove the warning, but it does work as I want it to, as I need a ScrollView and a FlatList.

testing Picker with Detox in React Native

I just started using Detox to test my react native app and I'm having some trouble to test Pickers. I basically need to be able to choose a value from a Picker! But it seems impossible!!
Here is my Picker:
<Picker
style={styles.picker}
itemStyle={styles.pickerItem}
testID="picker"
selectedValue={selectedValue}
onValueChange={this.updateValue}
>
<Picker.Item key={0} label="Choose one" value={null} />
{values.map(value => {
return (
<Picker.Item
key={value}
label={value}
value={value}
testID={value}
/>
);
})}
</Picker>
And here is my test:
await element(by.type("UIPickerView")).setColumnToValue(0, "Apple");
But all I get is an error message saying it was not possible to set the value because it doesn't exist, but it does! Cause I'm looking at it right now!
Does anyone knows the right way to set a value in a Picker?
Any help would be great!