skip to Main Content

Im working on a feature in a administrative panel which display the alerts inside of the applicacion.
I have 3 methods:

  1. GET => get the data from the DB
  2. UPDATE => update a alert depending of the ID
  3. 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


  1. The infinite loop is because of this dependency array:

    [updateAlerts, deleteAlert]
    

    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 and deleteAlertService do? If they modify state of any kind, that state would likely be the dependency for this effect. Though if that state is alerts 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 (or getAlertas?) after performing those operations. Not as a dependency of those operations.

    For example, your updateAlertService function may internally call getAlerts (or getAlertas?) after it has completed whatever it is updating.

    Login or Signup to reply.
  2. 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 call getAlerts from updateAlerts and deleteAlert

     const AlertList= () => {
        const [alerts, setAlerts] = useState([])
    
        const getAlerts = async () => {
          const data = await getAlertService()
          setAlerts(data)
        }
    
        const updateAlerta = async (updatedAlert) => {
          await updateAlertService(updatedAlert)
          getAlerts();
        }
    
        async function eliminarAlerta(alertID) {
          await deleteAlertService({ id: alertID})
          getAlerts();
        }
    
        // SET THE STATE
        useEffect(() => {
          getAlerts()
        }, [])
    
        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>
        )
      }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search