我正在尝试使用React Native将 Class组件转换为 Function 。
我的Search
组件允许用户搜索电影名称,而我正在进行API调用以向他显示所有对应的电影。
这是我的课堂内容:
class Search extends React.Component {
constructor(props) {
super(props);
this.searchedText = "";
this.page = 0
this.totalPages = 0
this.state = {
films: [],isLoading: false
}
}
_loadFilms() {
if (this.searchedText.length > 0) {
this.setState({ isLoading: true })
getFilmsFromApiWithSearchedText(this.searchedText,this.page+1).then(data => {
this.page = data.page
this.totalPages = data.total_pages
this.setState({
films: [ ...this.state.films,...data.results ],isLoading: false
})
})
}
}
_searchTextInputChanged(text) {
this.searchedText = text
}
_searchFilms() {
this.page = 0
this.totalPages = 0
this.setState({
films: [],},() => {
this._loadFilms()
})
}
render() {
return (
<View style={styles.main_container}>
<TextInput
style={styles.textinput}
placeholder='Titre du film'
onChangeText={(text) => this._searchTextInputChanged(text)}
onSubmitEditing={() => this._searchFilms()}
/>
<Button title='Rechercher' onPress={() => this._searchFilms()}/>
<flatList
data={this.state.films}
keyExtractor={(item) => item.id.toString()}
renderItem={({item}) => <FilmItem film={item}/>}
onEndReachedThreshold={0.5}
onEndReached={() => {
if (this.page < this.totalPages) {
this._loadFilms()
}
}}
/>
</View>
)
}
}
render() {
return (
<View>
<TextInput
onChangeText={(text) => this._searchTextInputChanged(text)}
onSubmitEditing={() => this._searchFilms()}
/>
<Button title='Search' onPress={() => this._searchFilms()}/>
<flatList
data={this.state.films}
keyExtractor={(item) => item.id.toString()}
renderItem={({item}) => <FilmItem film={item}/>}
onEndReachedThreshold={0.5}
onEndReached={() => {
if (this.page < this.totalPages) {
this._loadFilms()
}
}}
/>
{this._displayLoading()}
</View>
)
}
}
如何用钩子翻译以下内容:
-
this.page
和this.totalPages
?是useRef解决方案吗?
在 -
我正在使用
setState
回调在影片列表为空时进行新的API调用(因为这是一个新搜索)。但是之后立即执行此操作无效,因为setState
是异步的。 但是我找不到用钩子做到这一点的方法。
_searchFilms()
中,我认为useEffect
可以做到,但是
- 我只想在我的
film
列表为空时调用此API,因为我调用_searchFilms()
进行新搜索。 -
_loadFilms()
在用户滚动时被调用,以将更多电影添加到flatList(用于相同的搜索),因此在这种情况下我无法清除this.films
。
到目前为止,这是我的翻译方式:
const Search = () => {
const [searchText,setSearchText] = useState('');
const [films,setfilms] = useState([]);
// handle pagination
const page = useRef(0);
const totalPages = useRef(0);
// handle api fetch
const [isLoading,setIsLoading] = useState(false);
const loadFilmsFromApi = () => {
getFilmsFromApiWithSearchedText(searchText,page + 1).then((data) => {
page.current = data.page;
totalPages.current = data.total_pages;
setfilms(films => [...films,...data.results]);
setIsLoading(false);
})
};
const searchFilm = () => {
if (searchText.length > 0) {
page.current = 0;
totalPages.current = 0;
setfilms([]);
// HERE MY Films list won't be cleared (setState asynchronous)
loadFilmsFromApi();
// after the api call,clear input
setSearchText('');
}
};
useEffect(() => {
console.log(page,totalPages,"Film number" + films.length);
},[films]);