How to prevent flatlist header or footer from re-render in reactnative
Asked Answered
O

3

20

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>
              )}
            />
Ostrom answered 16/4, 2020 at 9:29 Comment(0)
G
29

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.

Grenadier answered 16/4, 2020 at 9:37 Comment(0)
M
18

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>)}
/>
Molly answered 5/12, 2021 at 7:24 Comment(0)
E
0

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.

Elkin answered 5/2, 2021 at 9:58 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.