我不确定为什么,但是我所做的事情导致我的intersectionObserver实例中的回调触发两次,而该触发仅触发一次。 任何关于为什么这样做的见解将不胜感激。
在此组件中发生的其他事情中,我试图通过在useEffect()挂钩内的我的观察者实例上调用observe方法,来设置insersectionObserver来观察我称为底边界的元素。这工作正常,只是观察者触发了我的回调两次。我已经尝试将观察者添加到依赖数组,并且尝试将getEvents添加到依赖数组,但是我只是一个无限循环,而不是双重攻击。
import React, { useState, useEffect, useReducer } from 'react';
import { BrowserRouter as Router, Route, Switch } from 'react-router-dom';
import CreatePromo from './components/promo/CreatePromo';
import MainStyle from './components/MainStyle';
import Home from './components/Home';
import SearchEvents from './components/SearchEvents';
import Social from './components/Social';
import SimpleExample from './components/EventLocationMap';
import PromoState from './components/context/PromoContext/PromoState';
import './tailwind.generated.css';
import 'react-quill/dist/quill.snow.css';
import './App.css';
// @TODO start using context api for global state management ASAP.
const App = () => {
//set initial createPromo widget state.
const [allEvents, setAllEvents] = useState([]);
const [promoState, setPromoState] = useState({
name: '',
type: '',
startDate: '',
startTime: '',
endDate: '',
endTime: '',
address: '',
city: '',
state: '',
postal: '',
description: '',
pictures: '',
files: null,
});
// options for the IntersectionObserver constructor below
let options = {
root: null,
rootMargin: '0px',
threshold: 1.0,
};
let eventsToShow = 0;
// instantiate intersection observer.
const observer = new IntersectionObserver((entries) => {
entries.forEach((entry) => {
console.log(entry);
console.log(entry.isIntersecting);
});
eventsToShow += 4;
console.log('trigger');
getEvents(eventsToShow);
}, options);
//defines our backend api call to get events
const getEvents = async (numberOfEvents) => {
try {
const events = await fetch(
`http://localhost:3001/api/events/${numberOfEvents}`
);
const newData = await events.json();
setAllEvents([...allEvents, ...newData]);
return newData;
} catch (error) {
console.log(error);
}
};
//wrapper function to add a new event to allEvents
const handleSetAllEvents = (newEvent) => {
setAllEvents([...allEvents, newEvent]);
};
//wrapper function for updating controlled form state
const handlePromoStateChange = (e) => {
setPromoState({ ...promoState, [e.target.name]: e.target.value });
};
//wrapper function for handling the react-quill rich-text input specifically
const handleDescriptionChange = (value) =>
setPromoState({ ...promoState, description: value });
useEffect(() => {
//loads more events when viewport intersects with #bottom-boundary
observer.observe(document.querySelector('#bottom-boundary'));
}, []);
return (
// <PromoState>
<Router>
<MainStyle>
<Switch>
<Route exact path='/'>
<Home allEvents={allEvents} />
</Route>
<Route exact path='/create'>
<CreatePromo
promoState={promoState}
handlePromoStateChange={handlePromoStateChange}
handleDescriptionChange={handleDescriptionChange}
handleSetAllEvents={handleSetAllEvents}
/>
</Route>
<Route path='/search'>
<SearchEvents />
</Route>
<Route path='/social'>
<Social />
</Route>
</Switch>
</MainStyle>
</Router>
// </PromoState>
);
};
export default App;
答案 0 :(得分:1)
您将在每次更新时创建一个新的观察者。这就是为什么将观察者添加到依赖数组会导致无限循环的原因。
尝试将创建IntersectionObserver
和相关功能移至useEffect
。
这样可以避免在每次更新时创建新的观察者。
此外,您可能想取消观察/销毁IntersectionObserver
效果清除。
要说为什么您的回调两次被触发却看不到输出,这并不容易。如果您可以在codesandbox / jsfiddle中附加最低限度的复制,将会更容易。
...
useEffect(() => {
let options = {
root: null,
rootMargin: '0px',
threshold: 1.0,
};
let eventsToShow = 0;
// instantiate intersection observer.
const observer = new IntersectionObserver((entries) => {
entries.forEach((entry) => {
console.log(entry);
console.log(entry.isIntersecting);
});
eventsToShow += 4;
console.log('trigger');
getEvents(eventsToShow);
}, options);
//defines our backend api call to get events
const getEvents = async (numberOfEvents) => {
try {
const events = await fetch(
`http://localhost:3001/api/events/${numberOfEvents}`
);
const newData = await events.json();
setAllEvents(allEvents => [...allEvents, ...newData]);
return newData;
} catch (error) {
console.log(error);
}
};
//loads more events when viewport intersects with #bottom-boundary
observer.observe(document.querySelector('#bottom-boundary'));
// destroy observer
return observer.disconnect;
}, []);
...
答案 1 :(得分:1)
我知道了。
当底部边界元素进入和退出视口时,触发了我的回调。可以通过forEach循环中的条件轻松检查条件,即检查entry.isIntersecting的值,并且仅在isIntersecting === true时才触发回调。