Reputation: 415
I put an input field in the footer of flatlist but when i try to type anything it dismiss the keyboard automatically because of the re-render of the flatlist footer..
I tried to nest the flatlist from Scrollview but this brings warning..
How can i stop the footer from being re-rendered? can i fix this without nest the flatlist from Scrollview?
<FlatList
ListHeaderComponent={() => (
<View style={styles.discountContainer}>
<Text style={[styles.buttonText, { letterSpacing: 3 }]}>
10% DISCOUNT ON 8 COURSES
</Text>
</View>
)}
numColumns={2}
data={data}
renderItem={({ item }) => (
<View>
<SingleProduct item={item} />
</View>
)}
ListFooterComponent={() => (
<View>
<View style={styles.couponContainer}>
<Input
placeholder='Coupon code'
placeholderTextColor='#0a5796'
color='#0a5796'
inputStyle={{
color: '#0a5796',
}}
inputContainerStyle={{
borderBottomWidth: 0,
height: 50,
}}
containerStyle={styles.couponInputContainer}
onChangeText={(value) =>
this.setState({ couponCode: value })
}
value={this.state.couponCode}
/>
{couponLoading ? (
<View style={styles.couponButton}>
<ActivityIndicator />
</View>
) : (
<TouchableOpacity
style={styles.couponButton}
onPress={() => this.codeCheck(couponCode, line_items)}
>
<Text style={styles.buttonText}>Apply Coupon</Text>
</TouchableOpacity>
)}
</View>
</View>
)}
/>
Upvotes: 21
Views: 10550
Reputation: 158
Another option is to use useMemo. If you want to write footer and header components separately, you can use useMemo. I am sharing an example below.
<FlatList
...
ListHeaderComponent={renderListHeader}
...
/>
const renderListHeader = useMemo(() => {
return <View/>;
}, []);
Upvotes: 0
Reputation: 571
If you are using Functional Component then don't use Arrow function () => (...)
for header and footer components of FlatList but instead only return your header and footer Components as shown in the sample below.
<FlatList
...
ListHeaderComponent={(<View><Text>Header</Text></View>)}
ListFooterComponent={(<View><Text>Footer<Text></View>)}
/>
Upvotes: 20
Reputation: 13628
Arrow-Funktions are "always" executed and create a new Reference in Memory. This way they will always re-rendering if component will be executed.
For performance reasons you better define your function outside and call it like this:
function renderMyItem(){ ...bimbom... yous stuff goes here! }
function renderHeader(){ ...bimbom... yous stuff goes here! }
<Flatlist
renderItem={this.renderMyItem()}
ListHeaderComponent={this.renderHeader()}
...
/>
What happens here?
Both of your functions renderMyItem
and renderHeader
will be executed once if your component is loaded and will be saved in memory. So every time you call one of the functions, you call a reference to the place in memory where they are saved.
In the other case, Arrow-Functions ()=>{...}
are executed in current context and generate a new reference in Memory, each time they called, because .. to say it clear: you define & call a function that way.
Upvotes: 30
Reputation: 5094
I was going through the same problem and the accepted answer didn't worked for me. As here the problem occurs because we are updating the state whenever the text changes (as defined in onChangeText
) which causes re-rendering. Thus i came up with another solution;
First i created another dict object newState
which has nothing to do with state or props. So on changing newState
dict, it will not cause re-rendering. Then;
newState = {}
<TextInput onChangeText={text => this.newState.value = text} />
Then i changed the state(which is necessary as per your problem and as per mine) on onEndEditing
;
<TextInput onChangeText={text => this.newState.value = text} onEndEditing={this.setSearch} />
Here is setSearch
setSearch= () => {
this.setState({couponCode: this.newState.value})
delete this.newState.value;
}
I am deleting the key after the state is set because it doesnot update correctly next time.
Upvotes: 0