如果我在 useEffect 中添加状态,useEffect 会继续获取我的数据
Posted
技术标签:
【中文标题】如果我在 useEffect 中添加状态,useEffect 会继续获取我的数据【英文标题】:useEffect keep fetching my data if I add state in useEffect 【发布时间】:2021-04-23 12:38:25 【问题描述】:当我在这样的数组中将 eventList 添加到我的 useEffect 中时:
const getEvents = async () =>
const res = await axios.get(`/api/v1/events/event/$teamId`);
setEventList(res.data.Events);
;
useEffect(() =>
getEvents();
, [eventList]);
它只是不停地获取数据
但是如果我不把 eventList 放在那里,我的页面只需获取一次,当我点击另一个组件时就会消失
添加的组件:
日历.js:
const Calendar = (props) =>
const teamId = props;
const events = [];
const [date, setDate] = useState(new Date());
const [eventList, setEventList] = useState([]);
const [expanded, setExpanded] = useState("");
const getEvents = async () =>
const res = await axios.get(`/api/v1/events/event/$teamId`);
setEventList(res.data.Events);
;
useEffect(() =>
getEvents();
, []);
const handleChangeAccordion = (panel) => (event, newExpanded) =>
setExpanded(newExpanded ? panel : false);
;
const handleChangeCalendar = (value) =>
const currentDate = moment(value).format("YYYY-MM-DD");
setDate(currentDate);
const currentEvents = events.find((event) =>
moment(currentDate).isSame(event.date, "day")
);
setEventList(currentEvents ? currentEvents.events : []);
;
const [showCalendarCard, setShowCalendarCard] = useState(false);
const addEvent = () =>
setShowCalendarCard(true);
;
return (
<div className="calendar-tab">
<div className="event-view-container">
<div className="event-date">
<p className="event-date-monthday">moment(date).format("D")</p>
<p className="event-date-weekday">moment(date).format("dddd")</p>
</div>
<div className="event-list">
eventList.map((event, index) => (
<div>
<Accordion
key=`event-$index`
square
expanded=expanded === `event$index + 1`
onChange=handleChangeAccordion(`event$index + 1`)
>
<AccordionSummary>
<div className="event-list-item-header">
<span className="timestart">
moment(event.timestart, "HH:mm:ss").format("h:mm A")
</span>
<span className="dash">-</span>
<span className="timeend">
moment(event.timeend, "HH:mm:ss").format("h:mm A")
</span>
<span className="title">event.title</span>
</div>
</AccordionSummary>
</Accordion>
<div className="event-list-item-content">
<div className="header">
<span className="announcements">Announcements</span>
<div className="plus">
<ControlPoint />
</div>
</div>
<div className="content">event.description</div>
</div>
</div>
))
</div>
</div>
<div className="calendar-view-container">
<div className="event-calendar-container">
!showCalendarCard ? (
<div>
<EventCalendar
className="event-calendar"
formatShortWeekday=(locale, date) =>
moment(date).format("dd").charAt(0)
tileClassName=( date ) =>
if (events.find((x) => moment(x.date).isSame(date, "day")))
return "highlight";
onChange=(value) => handleChangeCalendar(value)
nextLabel=<NavigateNext />
prevLabel=<NavigateBefore />
/>
<div className="add-event">
<ControlPoint onClick=addEvent />
</div>
</div>
) : (
<CalendarCard
setShowCalendarCard=setShowCalendarCard
teamId=teamId
/>
)
</div>
</div>
</div>
);
;
export default Calendar;
当我点击日历中的另一天时,它会显示我的事件列表。
这是我项目的照片:
【问题讨论】:
我建议使用某种计时器,而不是将 React 置于无限循环中。 @DBS 我该怎么做? 有一些体面的问题涵盖了这种事情,例如Polling api every x seconds with react 【参考方案1】:您的 useEffect 取决于 eventList
进行更改,并且通过调用该函数您正在更改 eventList
,如果您只想发送一次请求,那么这个解决方案就可以了
const Calendar = (props) =>
const teamId = props;
// const events = [];
const [date, setDate] = useState(new Date());
const [eventList, setEventList] = useState([]);
const [expanded, setExpanded] = useState("");
const getEvents = async () =>
const res = await axios.get(`/api/v1/events/event/$teamId`);
setEventList(res.data.Events);
;
useEffect(() =>
getEvents();
, []);
有一个空的依赖列表只会触发一次函数,所以改变
useEffect(() =>
getEvents();
, [eventList]);
到这里
useEffect(() =>
getEvents();
, []);
【讨论】:
但是如果我换成其他组件时只调用一次它就会消失 你能编辑你的问题并添加组件吗? 我刚刚编辑了它。因此,当我单击日历中的另一天时,数据将消失,当我单击返回创建日期时,它仍然消失【参考方案2】:它卡在一个循环中,因为您的 useEffect
回调具有改变它自己的依赖关系 (eventList
) 的副作用。
基本上不是重置您从 API 获取的事件列表,而是记住过滤后的列表
例如
const filteredEventList = useMemo(() =>
return eventList.filter((event) =>
moment(date).isSame(event.date, "day")
)
, [date, eventList])
然后在你的渲染中使用这个过滤的事件列表
【讨论】:
我该如何解决这个问题? 你需要更好地组织你的代码。避免在用户输入内容时点击 API。我会更详细地编辑。 更新了,看看吧。以上是关于如果我在 useEffect 中添加状态,useEffect 会继续获取我的数据的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 React Hooks 和 Context API 正确地将来自 useEffect 内部调用的多个端点的数据添加到状态对象?