这是我的post-component working.req函数在挂载时工作,当onScroll函数触发但挂钩不工作或从未触发时工作。总是第1页的值
const PostsComponent = () => {
const [totalPage, setTotalPage] = useState(1)
const [loading, setLoading] = useState(false)
const [tags, setTags] = useState([]);
const [haveMore, setHaveMore] = useState(null)
const { items } = useSelector(state => ({
items: state.posts.items
}));
const [page, setPage] = useState(1)
const dispatch = useDispatch();
const req = () => {
if (page <= totalPage) {
setLoading(true)
getPosts(page).then(res => {
res.posts.map(item => dispatch(getterPosts(item)));
res.posts.length > 0 ? setHaveMore(true) : setHaveMore(false)
setTotalPage(Math.ceil(res.total / 6));
}).finally(f => setLoading(false), setPage(page + 1));
}
};
const onScroll = event => {
const { scrollHeight, scrollTop, offsetHeight } = event.srcElement;
if (scrollTop + offsetHeight === scrollHeight) {
req();
}
};
};
服务的getPosts函数
export const getPosts = page => {
return new Promise((resolve, reject) => {
axios
.get(`${BASE_URL}/api/posts?page=${page}`)
.then(res => resolve(res.data))
.catch(err => reject(err.response.data.message));
});
};
有两个问题:
-
您的
page
变量在使用时可能已经过时,因为您的组件可能在finally
回调之前已经重新呈现。 -
这条线并没有做你想让它做的事情:
}).finally(f => setLoading(false), setPage(page + 1))
这样做是调用
setPage(page + 1)
,然后调用传递函数f => setLoading(false)
和值undefined
的finally
(调用setPage
的结果(。这是为了使用箭头函数的简洁形式而不使用逗号运算符的众多原因之一。
您可以通过修复它们
- 使用
setPage
的回调版本,该版本始终接收状态项的当前值 - 使用箭头函数的函数体形式,包含要在
finally
处理程序中进行的两个调用
像这样:
}).finally(f => {
setLoading(false);
setPage(p => p + 1);
});
我建议阅读Dan Abramov的这篇文章。表面上,这是关于useEffect
的,但在这一过程中,他很好地解释了诸如过时状态变量之类的事情。。。