I have a FlatList
<View style={styles.container}>
<FlatList data={this.state.restaurants}
renderItem={({ item }) => this.renderItem(item.restaurant)}
keyExtractor={restaurant => restaurant.key}
ListHeaderComponent={() => this.renderHeaderComponent()}
ItemSeparatorComponent={this.renderSeparator}/>
</View>
And have TextInput in header it. I am using TextInput as search bar.
renderHeaderComponent() {
return(
<View style={{ flexDirection: 'row', marginTop: 10, borderBottomColor: '#CED0CE', borderWidth: 1, borderColor: 'transparent' }}>
<Icon name='search' size={30} style={{ marginLeft: 10, marginRight: 10 }}/>
<TextInput
style={{height: 40, flex: 1}}
onChangeText={(text) => this.onChangeText(text)}
placeholder='Type text for search'
clearButtonMode='while-editing'
value={this.state.searchText}
/>
</View>
);
};
In onChangeMethod i filter my data.
onChangeText(text) {
const filteredRestaurants = _.filter(this.props.list, (restaurantObject) => {
const restaurant = restaurantObject.restaurant;
const result = restaurant.name.trim().toLowerCase().includes(text.trim().toLowerCase());
return result;
})
this.setState({
searchText: text,
restaurants: filteredRestaurants
});
}
The problem is following. When I type one symbol in TextInput then focus is lost immediately from TextInput? How can I keep focus in TextInput while typing?
When your onChange event fires, the callback calls setState with the new title value, which gets passed to your text field as a prop. At that point, React renders a new component, which is why you lose focus.
To set focus on an input field after rendering with React, we can assign a ref to the input element with the useRef hook. Then we call focus on the current value of the ref to focus on the input. to call useRef to create a ref and assign it to inputReference . Then we call inputReference.
React. memo is a higher order component. If your component renders the same result given the same props, you can wrap it in a call to React. memo for a performance boost in some cases by memoizing the result. This means that React will skip rendering the component, and reuse the last rendered result.
You need to use an auto-bound
method for this, as ListHeaderComponent
is of type ReactClass
, and your current method basically re-creates and re-binds its render
every time the data updates, which is not what you want. This concept is further explained in this comment
Anyway, for your example, to fix your issues you should
1) Change your ListHeaderComponent
prop to
ListHeaderComponent={this.renderListHeader}
2) Now you want to change your renderHeaderComponent
method to be an auto-bound method
, and by doing this a new render will not be instantiated every time you change data ( Or enter text into the `TextInput)
renderListHeader = () => (
<View style={{ flexDirection: 'row', marginTop: 10, borderBottomColor: '#CED0CE', borderWidth: 1, borderColor: 'transparent' }}>
<Icon name='search' size={30} style={{ marginLeft: 10, marginRight: 10 }}/>
<TextInput
style={{height: 40, flex: 1}}
onChangeText={(text) => this.onChangeText(text)}
placeholder='Type text for search'
clearButtonMode='while-editing'
value={this.state.searchText}
/>
</View>
)
I ran into this, and to solve it I wrapped the renderListHeader in a React.useMemo hook and passed the state hook as an item to the dependency array.
renderListHeader = useMemo(() => (
<View style={{ flexDirection: 'row', marginTop: 10, borderBottomColor: '#CED0CE', borderWidth: 1, borderColor: 'transparent' }}>
<Icon name='search' size={30} style={{ marginLeft: 10, marginRight: 10 }}/>
<TextInput
style={{height: 40, flex: 1}}
onChangeText={(text) => this.onChangeText(text)}
placeholder='Type text for search'
clearButtonMode='while-editing'
value={this.state.searchText}
/>
</View>
), [this.onChangeText])
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With