es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

El contexto de React está creando un bucle infinito al recuperar los datos del usuario.

Tengo un contexto de React, así que puedo guardar algunos datos y reutilizarlos donde quiera en mi proyecto de React. Aquí está el código en el que estoy trabajando:

“`
import React, { useState, createContext } from “react”
import apiRequest from “../axios”
import { getCookie } from “../Utils”
import jwt_decode from “jwt-decode”

export const UserContext = React.createContext()

export const UserProvider = (props) => {
const [value, setValue] = useState({
loading: false,
isLoggedIn: false,
userId: “”,
username: “”
})

const updateData = (toUpdate) => {
    setValue({...value, ...toUpdate})
}

const fetchUser = async (userId, key) => {
    await apiRequest("get", "/user/" + userId, null, () => {}, (data) => {
        updateData({
            loading: false,
            isLoggedIn: true,
            userId: userId,
            username: data.user.username
        })

    }, (errMessage) => {

        updateData({
            loading: false
        })

    }, key)
}

// cargar los datos del usuario si el token de acceso está establecido
const accessToken = getCookie("access")
if (accessToken && !value.loggedIn && !value.loading) {
    updateData({ loading: true })
    const { sub: userId } = jwt_decode(accessToken)
    fetchUser(userId, accessToken)              // si comento esto, entonces no hay un bucle infinito
}

const methods = {
    fetchUser,
    updateData
}

return (
    <usercontext.provider value="{[value," methods]}="">
        {props.children}
    </usercontext.provider>
)

}

Tengo comentada la línea donde se crea este ciclo. ¿Alguien puede decirme por qué se comporta así?

Tags:  , , , ,

Answer

  1. Avatar for davy.ai

    El código está creando un bucle infinito debido a que el componente UserProvider está obteniendo datos dentro de la función del componente, lo que provoca que el componente se vuelva a renderizar y llame nuevamente a la función fetchUser. Este bucle ocurre porque la función fetchUser actualiza el estado, lo que provoca un nuevo renderizado y una nueva llamada a la función fetchUser.

    Para solucionar esto, puedes mover la función fetchUser y la comprobación del token de acceso a un gancho useEffect. Esto asegurará que los datos se obtengan solo una vez, cuando se monte el componente.

    Aquí tienes un ejemplo de cómo puedes actualizar el código:

    import React, { useState, createContext, useEffect } from "react";
    import apiRequest from "../axios";
    import { getCookie } from "../Utils";
    import jwt_decode from "jwt-decode";
    
    export const UserContext = React.createContext();
    
    export const UserProvider = (props) => {
      const [value, setValue] = useState({
        loading: false,
        isLoggedIn: false,
        userId: "",
        username: ""
      });
    
      const updateData = (toUpdate) => {
        setValue({ ...value, ...toUpdate });
      };
    
      const fetchUser = async (userId, key) => {
        await apiRequest(
          "get",
          "/user/" + userId,
          null,
          () => {},
          (data) => {
            updateData({
              loading: false,
              isLoggedIn: true,
              userId: userId,
              username: data.user.username
            });
          },
          (errMessage) => {
            updateData({
              loading: false
            });
          },
          key
        );
      };
    
      useEffect(() => {
        const accessToken = getCookie("access");
    
        if (accessToken && !value.loggedIn && !value.loading) {
          updateData({ loading: true });
    
          const { sub: userId } = jwt_decode(accessToken);
          fetchUser(userId, accessToken);
        }
      }, []);
    
      const methods = {
        fetchUser,
        updateData
      };
    
      return (
        <usercontext.provider value="{[value," methods]}="">
          {props.children}
        </usercontext.provider>
      );
    };
    

    Con este código actualizado, la función fetchUser solo se llamará una vez, cuando se monte el componente, y no provocará un bucle infinito.

Comments are closed.