Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[FlatList] Issues Rendering a TextInput within FlatList > ListHeaderComponent #13365

Closed
joncursi opened this issue Apr 7, 2017 · 20 comments
Closed
Labels
Resolution: Locked This issue was locked by the bot.

Comments

@joncursi
Copy link
Contributor

joncursi commented Apr 7, 2017

I am trying to render a TextInput at the top of a FlatList so that the user can search / filter the list of data.

      <FlatList
        ...
        data={[...]}
        ListHeaderComponent={(): React$Element<*> => (
          <TextInput
            ...
            onChangeText={(value: string): void => this._onChangeText(value)}
            value={this.state.query}
            ...
          />
        )}
        ...
      />

Every time the value prop given to TextInput changes, the keyboard dismisses rather than staying active and allowing the user to type. It looks as though the entire TextInput component is unmounted and re-mounted, forcing this odd behavior.

I've used this pattern on ListView's renderHeader with great success. Would like to see it working on FlatList as well!

@parkerdan
Copy link

parkerdan commented Apr 11, 2017

^^ Yup.

I had to move it out.

<View style={{ flex:1 }}>
   <SearchBar {...searchBarProps} />
   <FlatList {...flatListProps} />
</View>

@joncursi
Copy link
Contributor Author

Thanks for the heads up. The problem with moving it out is that it won't scroll with the flat list though.

@parkerdan
Copy link

parkerdan commented Apr 12, 2017

Ah..Yes. That is why I also put it in the ListView renderHeader before.

Let's hope this is fixed soon

@hramos hramos changed the title Issues Rendering a TextInput within FlatList > ListHeaderComponent [FlatList] Issues Rendering a TextInput within FlatList > ListHeaderComponent Apr 25, 2017
@gregblass
Copy link

Ah. Yeah, definitely an issue IMO. Most other UX patterns I've seen with a search at the top of a list will scroll with the list (iOS messages, for example).

My ListView had a SearchBar being rendered from react-native-elements using renderHeader, and it worked great. If I'm forced to take it out of the list and have it stick to the top, I may wait to implement FlatList.

I'll keep an eye out here for updates.

@tmilewski
Copy link

Yeah, I'm running into this case as well. Attempting to use a TextInput to search a SectionList while still having it move with the rest of the items.

@angusmccloud
Copy link

Any progress on this issue? I'm trying to convert over from sgListView since FlatList doesn't have the invisible-rows issue, but if I can't search/filter the list it's much less valuable.

@gregblass
Copy link

I'm actually not experiencing this anymore. I've got search bars passed into header components and they work great wil flat lists and section lists.

@angusmccloud
Copy link

@gregblass do you have a code sample? I tried upgrading to rn45 to make sure it wasn't that, still no luck.

My code looks like:
Main Component



<FlatList
data={this.state.beerList}
ItemSeparatorComponent={() => }
ListHeaderComponent={() => }
initialNumToRender={20}
refreshing={this.state.dataFetching}
onRefresh={this.loadBeerList(0)}
keyExtractor={item => item.BeerId}
renderItem={({ item }) => (
<BeerTeaser {...item} pageName="BeerCellar" onPress={() => this.gotoBeerProfile(item.BeerId, unescape(item.BeerName), unescape(item.BeerImage), item.YourRating)} />
)}
keyboardShouldPersistTaps="always"
keyboardDismissMode="on-drag"
/>


Render Page Header Component (there's some more, but this is the key stuff):

<Image source={require('../images/pageheaders/headercellar.png')} style={styles.PageTopImage}>
<View style={{flex: 1, backgroundColor: 'rgba(220, 20, 60, 0.8)', flexDirection: 'column', alignItems: 'center', justifyContent: 'center',}}>
<View style={{justifyContent: 'center', alignItems: 'center'}}>
{topText}

{this.props.anonymousUser === false &&

<View style={{justifyContent: 'center', alignItems: 'center'}}>
{bottomText}{this.props.beerCellarText}

<View style={{justifyContent: 'center', width: 270, paddingTop: 10}}>
<TextInput
ref = "searchKeywords"
editable = {true}
autoCorrect = {true}
autoFocus = {false}
selectTextOnFocus={true}
autoCapitalize = "none"
placeholder = {searchBoxText}
returnKeyType = "go"
onChange={this.props.setSearchText.bind(this)}
underlineColorAndroid='transparent'
style={[styles.FormItem, styles.TextInputStyle, styles.FontSize16]}
/>


}


@joncursi
Copy link
Contributor Author

I'm also getting this issue still on the latest ReactNative.

@angusmccloud
Copy link

@joncursi here's how I got it to work:
The FlatList Component:
<FlatList
data={this.state.beerList}
ItemSeparatorComponent={() => }
ListHeaderComponent={this._headerComponent}
initialNumToRender={20}
refreshing={this.state.dataFetching}
extraData={this.state}
keyExtractor={item => item.BeerId}
renderItem={({ item }) => (
<BeerTeaser {...item} pageName="BeerCellar" onPress={() => this.gotoBeerProfile(item.BeerId, unescape(item.BeerName), unescape(item.BeerImage), item.YourRating)} />
)}
keyboardShouldPersistTaps="always"
keyboardDismissMode="on-drag"
/>

Then the _headerComponent function calls the headercomponent:
_headerComponent = () => ;

The key for getting the header to interact correctly (sorting and searching) was the extraData={this.state} line in the FlatList.

Good luck!

@joncursi
Copy link
Contributor Author

@angusmccloud thanks for posting. Tried it out in my app but wasn't successful. Anyone else get this to work? I'm about to yank my search bar out of the header and just deal with the poorer UX.

@joncursi
Copy link
Contributor Author

joncursi commented Sep 26, 2017

I'm happy to report that I was able to get this to work with a rather simple fix! Using the same example as posted in the original comment, I just rendered the ListHeaderComponent directly as a React Element instead of a render function:

      <FlatList
        ...
        data={[...]}
        ListHeaderComponent={
          <TextInput
            ...
            onChangeText={(value: string): void => this._onChangeText(value)}
            value={this.state.query}
            ...
          />
        }
        ...
      />

This enables React to properly diff the ListHeaderComponent prop across changes, keeping the original TextInput mounted and just changing the value.

@joncursi
Copy link
Contributor Author

joncursi commented Oct 7, 2017

Unfortunately, my workaround above doesn't quite work for SectionList, but that's another issue I guess.

@DanielBoening
Copy link

@joncursi Do you know why this helps exactly?

@connercms
Copy link

Still running into this issue in RN 0.51. @joncursi suggestion still seems to be the fix - instead of ListHeaderComponent={() => }, ListHeaderComponent={ } seems to work

@Andreyco
Copy link
Contributor

@connercms I believe, this is not an issue, but rather proper and expected way of passing Header component.

@dborzouei
Copy link

dborzouei commented Jan 25, 2018

just use "Arrow functions" like this sample

...

renderHeader = () => {
   return <TextInput
            ...
            onChangeText={(name): this.setState({name})}
            value={this.state.name}
            ...
          />
}

...

 <FlatList
        ...
        data={[...]}
        ListHeaderComponent={this.renderHeader()}
        ...
      />

It works for me
or just rendered the ListHeaderComponent directly as a React Element instead of a render function

@farukyesil
Copy link

farukyesil commented Jan 26, 2018 via email

@basitsattar
Copy link

Hi, guys any update? I am facing the same issue. If I render it as a separate component it works fine, otherwise text changes on input change.

@ruchi1906
Copy link

Thanks @angusmccloud . Adding extraData={this.state} this to FlatList worked for me

@facebook facebook locked as resolved and limited conversation to collaborators Sep 26, 2018
@react-native-bot react-native-bot added the Resolution: Locked This issue was locked by the bot. label Sep 26, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Resolution: Locked This issue was locked by the bot.
Projects
None yet
Development

No branches or pull requests