TL; DR:我正在尝试将基于类的App组件重构为Functional组件,并且用useEffect Hook获得了一些意外结果。
我对React还是很陌生,使用OMDB API搜索电影的应用程序版本是基于类的。它运行良好,所以我想在进入Redux之前对钩子和上下文进行更多练习。
在我的班级组件中,我有以下代码:
componentDidMount = () => {
window.onscroll = this.handleScroll;
};
handleScroll = () => {
if (!this.state.movies.loading) {
if (getScrollDownPercentage(window) > 0.8) {
const nextPage = this.state.movies.page + 1;
this.searchMovies(this.state.movies.searchValue, nextPage);
this.setState({
...this.state,
movies: {
...this.state.movies,
page: nextPage,
},
});
}
}
};
searchMovies = (str, page = 1) => {
const existingMovies =
this.state.movies.data.length && this.state.movies.searchValue === str
? this.state.movies.data
: [];
this.setState({
...this.state,
movies: {
...this.state.movies,
loading: true,
},
});
axios
.get(`${process.env.REACT_APP_ENDPOINT}s=${str}&page=${page}`)
.then((response) => {
if (response.data.Response === "True") {
this.setState({
...this.state,
movies: {
...this.state.movies,
loading: false,
searchValue: str,
data: [...existingMovies, ...response.data.Search],
},
});
}
});
};
重构后,我得到了下面的代码,它们看起来不太干净(所以与我希望实现的相反)
到达页面末尾的那一刻,我得到了不间断的axios调用流,在第2页和第3页之间切换
如果我没记错的话,那是行不通的,因为setState异步运行,并且我的页面上不断更新。
useEffect(() => {
window.onscroll = () => {
handleScroll();
};
if (searchValue) {
console.log(page);
searchMovies(searchValue, page);
}
return () => {
window.removeEventListener("scroll", handleScroll);
};
}, [searchValue, page]);
const handleScroll = () => {
if (!loading && searchValue) {
if (getScrollDownPercentage(window) > 0.7) {
setState({
...state,
movies: {
...state.movies,
page: page + 1,
},
});
}
}
};
const searchMovies = (str, page = 1) => {
const existingMovies = data.length && prevSearchValue === str ? data : [];
setState({
...state,
movies: {
...state.movies,
loading: true,
},
});
axios
.get(`${process.env.REACT_APP_ENDPOINT2}s=${str}&page=${page}`)
.then((response) => {
if (response.data.Response === "True") {
setState({
...state,
movies: {
...state.movies,
loading: false,
searchValue: str,
data: [...existingMovies, ...response.data.Search],
},
});
} else {
setState({
...state,
movies: {
...state.movies,
loading: false,
error: true,
},
});
}
});
};
我希望我能包括所有的内容(也不要太多),以阐明我的问题。寻找一些React向导。
编辑:进一步说明问题并以粗体显示
答案 0 :(得分:1)
鉴于您的回复,我想您想做多个useEffects
:一个用于searchMovies,另一个用于滚动设置。
useEffect(() => {
window.onscroll = () => {
handleScroll();
};
return () => {
window.removeEventListener("scroll", handleScroll);
};
}, []);
useEffect(() => {
if (searchValue) {
console.log(page);
searchMovies(searchValue, page);
}
}, [searchValue, page])
答案 1 :(得分:0)
一种快速解决方案是将一个空数组用作第二个参数,以避免无限循环
{{ user.first_name }}