#javascript #reactjs
Вопрос:
Я реализовал бесконечную прокрутку, чтобы получать больше данных всякий раз, когда пользователь достигает нижней части страницы. Кажется, это работает нормально, но у меня особое состояние.
Когда страница отображается в первый раз, я получаю ответ в виде :
count: 47
next: "http://localhost:8000/api/user/groups/56/users/?limit=20amp;offset=20"
previous: null
results: [{id: "79", email: "priyanka LarryLo@emembler.com", first_name: "Larry", last_name: "Lo",…},…]
Где count представляет общее количество элементов в массиве, в строке «далее» ограничение установлено равным 20, что означает, что я получаю максимум 20 элементов для каждого вызова api, и offest показывает, что для получения следующих элементов я должен дать смещение «20» при следующем вызове api.
Как только все данные будут извлечены, значение «next» будет равно нулю, поэтому я поставил условие примерно так: если значение «next» равно нулю, не вызывайте api, но вызов api будет дан.
Код редуктора для хранения извлекаемых данных:
case GET_MEMBERS_OF_GROUP: {
newState["nextMembers"] =action.payload.response.next;
if (action.payload.response.results) {
let newArray = newState["members"].concat(
action.payload.response.results
);
newState["members"] = newArray;
} else {
newState["members"] = action.payload.response.results;
}
if(action.payload.page == 0){
newState["members"] = action.payload.response.results
}
return newState;
}
У меня есть еще один редуктор для обновления смещения, которое будет предоставлено при следующем вызове api:
case SHOW_NEXT_MEMBERS: {
newState["pageOfmembers"] = newState["pageOfmembers"] action.payload.nextMembers;
return newState;
}
Реализация бесконечной прокрутки, где смещение не увеличивается, а также когда значение «следующий» равно нулю, вызывается api:
const [nextmembers, setNextmembers] = useState()
useEffect(() => {
setNextmembers(data.nextMembers)
},[data.nextMembers])
useEffect(() => {
const event = window.addEventListener('scroll', () => {
if ((window.innerHeight window.scrollY) == document.body.scrollHeight ) {
if(nextmembersamp;amp; window.location.href.includes("/members")){
dispatch({
type: SHOW_NEXT_MEMBERS,
payload: {
nextMembers: 20,
},
})
setTimeout(() => {
dispatch(EMDoGetMembersOfGroupAction({id:data.singleGroup.id ? data.singleGroup.id : window.sessionStorage.getItem("GroupId"), limit:data.pageOfmembers}))
},500)
}
}
})
return () => window.removeEventListener('scroll', event);
}, [nextmembers])
Комментарии:
1. addEventListener возвращает неопределенное значение ( developer.mozilla.org/en-US/docs/Web/API/EventTarget/… ). Таким образом, переменная события должна быть неопределенной, и removeEventListener ничего не делает. Вам нужно будет сохранить функцию обработки событий в переменной, а затем использовать эту переменную в addEventListener и removeEventListener.
2. Не могли бы вы привести мне один пример с моим существующим кодом?
Ответ №1:
Так что это может быть не все решение, но часть проблемы заключается в том, как вы используете addEventListener и removeEventListener. Вам нужно сохранить функцию обработки событий в переменной, а затем использовать эту переменную с помощью addEventListener и removeEventListener.
const [nextmembers, setNextmembers] = useState()
useEffect(() => {
setNextmembers(data.nextMembers)
},[data.nextMembers])
const handleScroll = useCallback(() => {
// all the logic in that anonymous function goes here
if ((window.innerHeight window.scrollY) == document.body.scrollHeight ){
// ...
}
}, [!!nextMembers])
useEffect(() => {
window.addEventListener('scroll', handleScroll)
return () => window.removeEventListener('scroll', handleScroll)
}, [handleScroll])