Does nesting FlatList inside ScrollView hinder it's performance? - react-native

I've got following layout setup:
<ScrollView>
<MyCustomView />
<FlatList />
</ScrollView>
At the moment it is working as I intended it to work i.e. user scrolls past a custom view and then hits flat list with many items in it and can continue scrolling down.
My concern is that such layout is not what FlatList is intended for i.e. will it still only render items as they are needed?

Yep, I don't think it would create much of problem here.
As Flatlist too is an kind of scrollview so it won't cause much issue over here.
Also it would be a better approach if you keep that under flatlist and fix the view you have to hit using stickyIndices which you can get in flatlist and without comprising any rendering issues or performance hitches.
<FlatList
data={ this.state.FlatListItems }
ItemSeparatorComponent={ this.FlatListItemSeparator}
renderItem={ ({item}) => (
<Text
style={styles.FlatList_Item}
onPress={this.GetItem.bind(this, item.key)}> {item.key}
</Text>
)}
ListHeaderComponent={this.Render_FlatList_Sticky_header}
stickyHeaderIndices={[0]}
/>

Flat list inside scroll view create some kind of performance issue so for solving this you need to take care of some things for more info refer to link below
https://medium.com/sanjagh/how-to-optimize-your-react-native-flatlist-946490c8c49b

Related

Data within modal not reflecting the data being passed

I am hoping someone can point what I am misunderstanding. I have placed console.log around the code but feel like I am missing something important. The way it is done is:
1 - Grab a collection of items
2 - Pass items data down to the model that support to open
3 - When open model it should show that specific item click info
PROBLEM: I am seeing the same data for every modal I keep clicking to open. Is there a reason why the data seems to be the same even though I am iterating using a FlatList
<FlatList<any>
numColumns={2}
contentContainerStyle={{
alignItems: "center",
}}
data={items}
keyExtractor={(item) => item.id}
renderItem={renderImages}
/>
return (
<View key={item.id}>
<MiniProfileModal
id={item.id}
url={item.imageURL}
userName={item.title}
showModal={showModal}
setShowModal={setShowModal}
/>
</View>
);
In most cases, Modals are not rendered on the same component tree as other components. This has more benefits as modal can overlay other components and state changes in other components will not affect modal rerender which improves performance.
To solve this problem, you need to force the modal to rerender when new items are selected to keep up with those changes.

react-native: OnEndReached for Flatlist not working in scrollview

I'm new on ReactNative development and I'm developing my first application.
I'm trying to use OnEndReached in a flat list which is in a scrollview tab. I use this scrollview because I have 3 flat lists in my application.
The first two are horizontal. For the last one, I need to handle the pagination with the onEndReached. But, When I put this last flat list in the scroll view, it doesn't work at all without any issues.
When I put it out of the scrollview, it works correctly. So I assume the issue is related to that.
Do you know how I can manage this issue? I'm sorry if this question is a basic one :(
OnEndReached doesn't call if the parent has ScrollView. Why not put those top views in the Header?
<FlatList
data={data}
renderItem={}
keyExtractor={(item, index) => item.personId}
onEndReached={() => {
console.log(" On End Reached");
}}
onEndReachedThreshold={0.01}
ListHeaderComponent={() => (
<View>
<FlatList/>
<FlatList/>
</View>
))
/>

Render FlatList footer at the bottom of the list even if content is not enough

I want to render FlatList's footer at the bottom of the page even if there is not enough content to fill the whole screen.
In order to do this, you need to take a look at react-native sources.
Here there is a code which shows adding footer internally.
As you can see it wraps into additional View which can be styled using ListFooterComponentStyle prop. It's not described for some reason in docs.
So here is the solution:
<FlatList
data={someData}
keyExtractor={item => item.id}
contentContainerStyle={{flexGrow: 1}}
ListFooterComponentStyle={{flex:1, justifyContent: 'flex-end'}}
ListFooterComponent={<Footer/>}
...
/>
UPD: Update answer using AtlasRider's comment.

React native SectionList horizontal mode

I've got a question. I've been trying to use SectionList for render a list section but the problem is I want to use list in horizontal mode and I don't know how to do that.
Please help I've stuck on this for 2 hours.
This is my code:
<SectionList
renderItem={({item}) => <Image source={require('../assets/images/img1.jpg')} />}
renderSectionHeader={({section}) => <Text>{section.title}</Text>}
sections={dataSource}
/>
In ReactNative docs, there is no prop for making horizontal SectionList(as of 0.48), but its parent VirtualizedList has.
Hence just try if it works ...
<SectionList
horizontal={true}
/>
If it does not work then probably u should try using Flatlist which has a horizontal prop and wait until it's implemented for SectionList

React Native Touchable is disabling ScrollView

I'm new to React Native, so am probably asking something very obvious, but please help.
I have a view wrapped in a touchable, so that the whole area responds to tapping. Then have a ScrollView nested inside the view. The overall structure is something like this:
<TouchableWithoutFeedback onPress={this.handlePress.bind(this)}>
<View>
<ScrollView>
<Text>Hello, here is a very long text that needs scrolling.</Text>
<ScrollView>
</View>
</TouchableWithoutFeedback>
When this compiles and runs, the tapping is detected, but the scroll view doesn't scroll at all. I made the above code short and simple, but each component has the proper styling and I can see everything rendering fine and the long text is cutoff at the bottom of the ScrollView. Please help.
Thank you!
This is what worked for me:
<TouchableWithoutFeedback onPress={...}>
<View>
<ScrollView>
<View onStartShouldSetResponder={() => true}>
// Scrollable content
</View>
</ScrollView>
</View>
</TouchableWithoutFeedback>
The onStartShouldSetResponder prop stops the touch event propagation towards the TouchableWithoutFeedback element.
I'm using this structure it's working for me:
<TouchableWithoutFeedback onPress={() => {}}>
{other content}
<View onStartShouldSetResponder={() => true}>
<ScrollView>
{scrollable content}
</ScrollView>
</View>
</TouchableWithoutFeedback>
You can have a scrollView or FlatList inside a TouchableWithoutFeedback. Tho you shouldn't but some times you have no other choice to go. Taking a good look at this questions and answer validates that.
close react native modal by clicking on overlay,
how to dismiss modal by tapping screen in react native.
For the Question, The only way you can make it work (atleast that i know of), or the simplest way is to add a TouchableOpacity around Text in your code like this,
<TouchableWithoutFeedback onPress={this.handlePress.bind(this)}>
<View>
<ScrollView>
<TouchableOpacity>
<Text>Hello, here is a very long text that needs scrolling.</Text>
</TouchableOpacity>
<ScrollView>
</View>
</TouchableWithoutFeedback>
Note: TouchableOpacity is a wrapper for making Views respond properly to touches so automatically you can style it the way you would have styled your View Component then set some of its special props to whatever you want e.g activeOpacity etc. Moreso you can use TouchableHighlight it works, but it receives one child element i.e you enclose all your component inside a parent one.
I'm using this structure it's working for me:
<TouchableOpacity>
{other content}
<ScrollView>
<TouchableOpacity activeOpacity={1}>
{scrollable content}
</TouchableOpacity>
</ScrollView>
I found that for my situation the other examples did not work as they disabled the ability to click or disabled the ability to scroll. I instead used:
<FlatList
data={[{key: text1 }, { key: text2 } ...]}
renderItem={({ item }) => (
<TouchableWithoutFeedback onPress={this.onPressContent}>
<Text style={styles.text}>{item.key}</Text>
</TouchableWithoutFeedback>
)}
/>
I happend to need to multiple chunks but you could use single element in the data array for one piece of text.
This let the press event to fire as well as let the text scroll.
Trying to use a ScrollView component inside a TouchableWithoutFeedback component can cause some unexpected behavior because the TouchableWithoutFeedback component is designed to capture user gestures and trigger an action, but the ScrollView component is designed to allow users to scroll through content.Here is what the official docs say
Do not use unless you have a very good reason. All elements that
respond to press should have a visual feedback when touched.
TouchableWithoutFeedback supports only one child. If you wish to have
several child components, wrap them in a View. Importantly,
TouchableWithoutFeedback works by cloning its child and applying
responder props to it. It is therefore required that any intermediary
components pass through those props to the underlying React Native
component.
Thats write , you cannot have a scroll view inside the TouchableWithoutFeedback, it the property of react native that it will disable it, you can instead have your scroll view outside the TouchableWithoutFeedback tab and add the other contents that you want upon the click inside a view tag.
You can also use the Touchable Highlights instead, if the TouchableWithoutFeedback does not works.