Im working on a feature in a administrative panel which display the alerts inside of the applicacion.
I have 3 methods:
- GET => get the data from the DB
- UPDATE => update a alert depending of the ID
- DELETE => delete the alert depending of the ID
I wanted to use a useeffect and specifying that when to UPDATE or DELETE method is execute it. Triggers the GET method and set a new state with the updated data.
// NEW FEAUTURE: ALERTS
const AlertList= () => {
const [alerts, setAlerts] = useState([])
const getAlerts = async () => {
const data = await getAlertService()
setAlerts(data)
}
const updateAlerts = async (updatedAlert) => {
await updateAlertService(updatedAlert)
}
async function deleteAlert(alertID) {
await deleteAlertService({ id: alertID})
}
// SET THE STATE
useEffect(() => {
getAlertas()
}, [])
// WHEN THE UPDATE OR DELETE METHOD IS EXECUTE IT.RUN THE GETALERTS TO UPDATE THE STATE
useEffect(() => {
getAlertas()
}, [updateAlerts, deleteAlert])
return (
<div className="container container--flex--centered">
<div className="dashboard--title--container">
<h1 className="title">Alertas</h1>
</div>
<FiltroAlertas setAlertas={setAlertas}/>
<WidgetAlertas alertas={alertas} eliminarAlerta={eliminarAlerta} actualizarAlerta={updateAlerta}/>
</div>
)
}
The problem is that create a infinite loop. I dont know why
I wanted to add the useeffect to just listen. When the update or delete method is execute it. Run the function getAlerts to bringing the updated data and set the new state.
2
Answers
The infinite loop is because of this dependency array:
Those are functions, not data. And those functions are re-declared and re-created on every render. So this effect is triggered on every render. And this effect updates state, which triggers a re-render. Which triggers this effect. Which updates state. Etc. Etc.
(Or at least, that appears to be what’s happening. We don’t know what
getAlertas()
does, since it’s not shown here.)What do
updateAlertService
anddeleteAlertService
do? If they modify state of any kind, that state would likely be the dependency for this effect. Though if that state isalerts
then you shouldn’t need to re-fetch it after updating it. If those operations are invoking server-side changes, once that is complete you can just update client-side state accordingly.Or, if you want to ensure the data is synchronized with other potential server-side changes, you’d re-invoke
getAlerts
(orgetAlertas
?) after performing those operations. Not as a dependency of those operations.For example, your
updateAlertService
function may internally callgetAlerts
(orgetAlertas
?) after it has completed whatever it is updating.A function is still a variable. Adding a local function as a dependency of
useEffect
will run that effect every time your component renders. Given that the body of the effect also changes state, you get the infinite re-render.useEffect
isn’t helpful here, you can callgetAlerts
fromupdateAlerts
anddeleteAlert