I use a FlatList to display search results.
<View>
<FlatList
data={this.state.films}
keyExtractor={(item) => item.id.toString()}
renderItem={({item}) => <FilmItem film={item}/>}
/>
</View>
However, when the user starts a second search, this list does not restart to index 0. So I would like to add ScrollToIndex or viewPosition. I tried this but it doesn't work :
<View>
<FlatList
data={this.state.films}
keyExtractor={(item) => item.id.toString()}
renderItem={({item}) => <FilmItem film={item}/>}
scrollToItem={(index) => {0}}
/>
</View>
Could you please explain me why this is wrong and what would be the best solution ?
Thanks a lot,
Try this... I made a bunch of changes and have put comments:
// Components/Search.js
import React from "react";
import {StyleSheet, View, TextInput, Button, Text, FlatList, ActivityIndicator} from "react-native";
import FilmItem from "./filmItem";
import {getFilmsFromApiWithSearchedText} from "../API/TMDBApi";
class Search extends React.Component {
flatListRef = null; // declaring this here to make it explicit that we have this available
constructor(props) {
super(props);
this.searchedText = "";
this.state = {
films: [],
isLoading: false,
};
}
_loadFilms = () => {
// needs to be an arrow function so `this` is bound to this component
this.scrollToIndex(); // assumed you meant to actually call this?
if (this.searchedText.length > 0) {
this.setState({isLoading: true});
getFilmsFromApiWithSearchedText(this.searchedText).then(data => {
this.setState({
films: data.results,
isLoading: false,
});
});
}
};
// needs arrow to use `this`
_searchTextInputChanged = text => {
this.searchedText = text;
};
// needs arrow to use `this`
_displayLoading = () => {
// better to return null if not loading, otherwise return loading indicator
if (!this.state.isLoading) return null;
return (
<View style={styles.loading_container}>
<ActivityIndicator size='large' />
</View>
);
};
scrollToIndex = () => {
// you previously had this inside another method
this.flatListRef && this.flatListRef.scrollToIndex({index: 1}); // checking it exists first
};
render() {
return (
<View style={styles.main_container}>
<TextInput
style={styles.textinput}
placeholder='Titre du film'
onChangeText={text => this._searchTextInputChanged(text)}
onSubmitEditing={this._loadFilms} // no need to create a new anonymous function here
/>
<Button title='Rechercher' onPress={this._loadFilms} />
<View>
<FlatList
data={this.state.films}
ref={ref => (this.flatListRef = ref)}
keyExtractor={item => item.id.toString()}
onEndReachedThreshold={1} // corrected typo
onEndReached={() => {
console.log("TOC");
}}
renderItem={({item}) => <FilmItem film={item} />}
/>
</View>
{this._displayLoading()}
</View>
);
}
}
const styles = StyleSheet.create({
main_container: {
marginTop: 60,
padding: 15,
flex: 1,
},
loading_container: {
position: "absolute",
left: 0,
right: 0,
top: 100,
bottom: 0,
alignItems: "center",
paddingTop: 50,
backgroundColor: "white",
},
textinput: {
height: 50,
borderColor: "#999999",
borderWidth: 1,
paddingLeft: 5,
},
});
export default Search;