My useEffect is running multiple times per load even when the useEffect dependency isn't being updated. See console.log("filtering events"). Every time the page is loaded the useEffect runs three times (my best guess is because the components are being rendered three times?).
What I am trying to do is every time the filters
state variable is updated I want the filteredEvents
variable to be updated from the filters applied to all of the events and then the calendar component to be re-rendered with the new events.
import React, { useState, useEffect, useCallback } from 'react'
import { Calendar as BigCalendar, momentLocalizer } from 'react-big-calendar';
import moment from 'moment';
import loadingIMG from "../../../assets/images/courses/signup/minionsLoading.gif"
import "react-big-calendar/lib/css/react-big-calendar.css"
import {
Accordion,
AccordionItem,
AccordionItemHeading,
AccordionItemPanel,
AccordionItemButton
} from 'react-accessible-accordion'
import { navigate, Link } from 'gatsby';
moment.locale('en-US')
const localizer = momentLocalizer(moment)
const CourseSignup = ({className}) => {
const [loading, isLoading] = useState(true)
const [allEvents, setAllEvents] = useState({
count: undefined,
events: undefined
})
useEffect(async () => {
console.log("fetching events")
await fetch("http://127.0.0.1:5000/timeslots", {
method: 'GET',
headers: {
'X-API-Key': '*F-JaNdRgUkXp2s5v8x/A?D(G+KbPeSh',
}
})
.then(response => response.json())
.then((results) => {
let temp = []
// Get all events
for (var i = 0; i < results.events.length; i++) {
// TODO: Check if class is virtual or in-person
// TODO: Check if class is group or 1 on 1
// TODO: get teacher name
// TODO: get class name
// Get all neccesary information and push to an array
temp.push({
title: String(results.events[i].summary),
info: {
format: undefined,
type: undefined,
name: undefined,
teacher: undefined
},
description: String(results.events[i].description) || undefined,
start: new Date(results.events[i].start.date || results.events[i].start.dateTime),
end: new Date(results.events[i].end.date || results.events[i].end.dateTime),
url: String(results.events[i].htmlLink),
id: String(results.events[i].id),
est_locale_timecodes: {
start: results.events[i].start.date || results.events[i].start.dateTime,
end: results.events[i].end.date || results.events[i].end.dateTime
}
})
}
// update state variable with events
setAllEvents({
'count': temp.length,
'events': temp
})
})
.catch(() => {
// incase of an error replace all events
setAllEvents({
'count': undefined,
'events': undefined
})
})
.then(() => isLoading(false))
}, [])
const UserInterface = () => {
const [filters, updateFilters] = useState({
classTeacher: 'undefined', // name of the teacher (default: undefined)
classType: undefined, // 'group', '1 on 1'
classFormat: undefined, // 'virtual', 'in-person'
class: className // name of class (default: undefined)
})
const [filteredEvents, setFilteredEvents] = useState({
count: undefined,
events: undefined
})
useEffect(() => {
console.log("filtering events")
if(!Object.values(filters).every(filterValue => filterValue == undefined)) {
// let filtered = Array(allEvents.events).filter(event => {
// if(event.info.format == undefined || String(event.info.format).includes(filters.classFormat == undefined ? "" : filters.classFormat)) return true
// if(event.info.type == undefined || String(event.info.type).includes(filters.classType == undefined ? "" : filters.classType)) return true
// if(event.info.name == undefined || String(event.info.name).includes(filters.class == undefined ? "" : filters.class)) return true
// if(event.info.teacher == undefined || String(event.info.teacher).includes(filters.classTeacher == undefined ? "" : filters.classTeacher)) return true
// return false
// })
setFilteredEvents(allEvents)
} else {
setFilteredEvents(allEvents)
}
}, [filters])
const FilterOptions = () => {
return null
}
const Calendar = () => {
const getDate = () => {
var d = new Date()
return (`${d.toLocaleString('default', { month: 'long' })}, ${d.getFullYear()}`)
}
return (
<div id="calendar-content">
<div className="section-title" style={{"marginBottom":"10px"}}>
<h3 style={{fontFamily: "inherit"}}>{getDate()}</h3>
</div>
<BigCalendar
localizer={localizer}
events={filteredEvents.events}
startAccessor="start"
endAccessor="end"
style={{ height: 800 }}
views={{month: true}}
popup={true}
toolbar={false}
/>
</div>
)
}
const SignupForm = () => {
return null
}
return (
<div>
<FilterOptions/>
<div>
{loading
? null
: <Calendar/>
}
</div>
<SignupForm/>
</div>
)
}
return (
<UserInterface/>
)
}
export default CourseSignup