I have two FlatLists in my react native component. They are filled with similar data and about 80 items for the second FlatList. When the first FlatList reaches 11 items or more (I'm adding dynamically items to the first FlatList), the second one stops rendering items, and it is empty even if the choice for the filter is correct.
This is the first FlatList:
<FlatList
style={styles.flatList}
data={todaySuggestions}
renderItem={this.renderSuggestionItem}
keyExtractor={this.keyExtractor}
extraData={this.props}
/>
And the second one is:
<FlatList
style={styles.flatList}
data={data.filter(item => !completedItems.find(item1 => item1.id === item.id).completed)}
renderItem={this.renderFurtherSuggestionItem}
keyExtractor={this.keyExtractor}
extraData={this.props}
/>
when state change, Flatlist don't rerender again. if you want to rerender it again should use :
<FlatList
data:{yourData}
extraData:{this.state.yourState}
renderItem={this.yourRenderItem}
/>
instead of yourState you should use the state that when it changed, you need to rerender your flatlist.
Solved this one by adding another condition for filter, removing it from renderFurtherSuggestionItem function. In the other case, FlatList won't notice change of the data.
Related
I am using flatlist to show the results of different games, I want my users to change the order as they wish for that I used draggable flatlist function, the problem is i can drag the game but it couldn't place where i want it always comes back to its original position as in API.
Here is the code for flatlist function
<DraggableFlatList
data={this.state.dataSource}
onDragEnd={this.dataSource}
renderItem={this.renderItem}
keyExtractor={item => item.GameId.toString()}
ItemSeparatorComponent={this.renderSeprator}
refreshing = {this.state.refreshing}
onRefresh = {this.handleRefresh}
refreshControl={
<RefreshControl refreshing={this.refreshing} onRefresh={this.getS}
/>
}
/>
I'm creating a similar to netflix app. I have the below use case:
movies.map((movie) => (
<Grid item key={movie.imdbID}>
<Card movie={movie} onIconClick={onIconClick} />
</Grid>
))
I'm wrapping Card component under React.memo but even when one of the movie (watched flag inside it) changes, all the Cards get rendered.
Somehow Card is not getting memoized.
What I might be doing wrong?
How do I prevent re-rendering of all the movies when user has only clicked one card and only that card needs to be updated?
I'm trying to put a flatlist checklist into a react native tab view, to do that you need to declare the flatlist as a const so it can be used like . Unfortunately whenever I click on an item at the bottom of the list it pops back to the top and rerenders the list. This problem doesn't occur when a flatlist is rendered directly into your components render function.
I've made a simplified version of what I mean.
https://snack.expo.io/ecO7YYlVZ Is the version where clicking an item pops to the top
https://snack.expo.io/1iQ!ILk4B Is the version where clicking an item doesn't pop to the top.
The only difference between the two is the not working version is like this
const Dat = () => {
return (
<FlatList
style={styles.container}
data={rowsData}
renderItem={this.renderItem}
keyExtractor={extractKey}
/>
);
};
return <Dat />;
Whereas the working version is like this
return (
<FlatList
style={styles.container}
data={rowsData}
renderItem={this.renderItem}
keyExtractor={extractKey}
/>
);
EDIT: I need to have the flatlist in a way that I can add it to a tab using react-native-tab-view: https://github.com/react-native-community/react-native-tab-view
Dat component must be outside of render()
because it reinitializes the whole component and then rerenders that
which cause that behavior
instead, when you create a component outside of the render(), the component itself does not reinitialize only data updated
Your Dat component
const Dat = () => {
return (
<FlatList
style={styles.container}
data={rowsData}
renderItem={this.renderItem}
keyExtractor={extractKey}
/>
);
};
Check the example with the outside of render()
https://snack.expo.io/#jsfit/flatlist
I'm testing a FlatList nested in a Navigator and trying to learn how it works. The code below works fine:
<FlatList
data={[{key: 'a'}, {key: 'b'}]}
renderItem={({item}) => <Text>{item.key}</Text>}
horizontal={true}
/>
But this does not:
<FlatList
data={[{key: 'a'}, {key: 'b'}]}
renderItem={({item}) => <TextComp data={item}/>}
horizontal={true}
/>
TextComp is just a component that displays item.key and it works as intended when tested separately. The code is
<View>
<Text>{this.props.data.key}</Text>
</View>
I've also tried drawing borders around both components and it seems that the FlatList is definitely rendering, but the items are not.
I am testing on my Android device.
Update: I added console.log(this.props) statement to the TextComp component and it displays the props correctly, so the the correct data is being passed from the FlatList to TextComp, but TextComp is just not getting rendered.
Marcel Kalveram got the solution here after I compared his code with mine. Turns out, a height and width are required for the item to render correctly in the FlatList. The explanation I figured for this is that the item's dimensions are required to properly size the item within the FlatList. Similarly, an item's dimensions cannot be percentages since its parent is a FlatList, which has varying dimensions itself. Therefore, the solution to my problem was to add width and height style attributes to the item component. To make it automatically resize, I used built-in React Native Dimensions.
Suppose the app have a menu lists on the left, every menu reuses same content component on the right.(I use react-redux)
If I click the menu, the menu state update and the content component will load different data and do some other actions. But after the first load the content component will not execute componentWillMount, componentDidMount,it only has componentWillReceiveProps...etc. It is complex to handle the similar state. I hope the component will reload every time so that I can handle the state in componentDidMount. Is it about Class and Instance ? I hope get some good advice.
I have solved previous problem,but there is a bug about RefreshControl of ScrollView or ListView. Next is the code of content component:
<View style={{flex: 1}}>
<ListView
<RefreshControl
refreshing = {tableFetching || refreshTable}
onRefresh = {this._onRefresh}
tintColor = "gray"
title = "loading..." />
enableEmptySections = {true}
dataSource={ds.cloneWithRows(tableData)}
renderRow={this.renderRow}
style={{flex: 1}} />
</View>
When the component load firstly, the RefreshControl shows normally. But when I change the menu, the component update and load the new datas, the RefreshControl indicator doesn't show , it scroll to the above not to see.
What I see is that you are not able to manage the state. First of all componentWillMount and componentDidMount will work only for the first time until you don't move it out from the navigator stack(popRoute). In your case you don't want to pop the route to manage state so you can use other lifecycle components such as componentWillRecieveProps(),shouldComponentUpdate() etc. I have one more rescue plan for you, the forceUpdate() function which will update the component forcefully, but usage of it is prohibited until and unless there is no otherway.
Cheers:)