Estoy usando React-native y en él tengo un Hook personalizado llamado useUser que obtiene la información del usuario de AWS Amplify usando el método Auth.getUserInfro , y luego obtiene parte del objeto devuelto y establece una variable de estado con él. También tengo otro Hook llamado useData hook que obtiene algunos datos basados en el ID de usuario y los establece en una variable de estado.
useUser custom-Hook:
import React, { useState, useEffect } from "react"; import { Auth } from "aws-amplify"; const getUserInfo = async () => { try { const userInfo = await Auth.currentUserInfo(); const userId = userInfo?.attributes?.sub; return userId; } catch (e) { console.log("Failed to get the AuthUserId", e); } }; const useUserId = () => { const [id, setId] = useState(""); useEffect(() => { getUserInfo().then((userId) => { setId(userId); }); }, []); return id; }; export default useUserId; import useUserId from "./UseUserId"; // ...rest of the necessary imports const fetchData = async (userId) = > { // code to fetch data from GraphQl} const useData = () => { const [data, setData] = useState(); useEffect(() => { const userId = useUser(); fetchData(userId).then( // the rest of the code to set the state variable data.) },[]) return data }Cuando trato de hacer esto me sale un error que me dice
*Error: llamada de gancho no válida. Los ganchos solo se pueden llamar dentro del cuerpo de un componente de función. Esto podría suceder por una de las siguientes razones:
Creo que el problema es que estoy llamando a Hook useUser dentro del efecto de uso, pero usarlo dentro de la función causará el problema descrito aquí , y no puedo usarlo fuera del cuerpo de fetchData ya que useData en sí mismo es un hook, y solo se puede usar dentro del cuerpo de un componente funcional o Hook. Así que no sé cómo encontrar una manera de evitar este problema.
Correcto, los ganchos de React solo se pueden llamar desde los componentes de la función React y otros ganchos de React. La devolución de llamada del gancho useEffect no es un gancho React, es una devolución de llamada. De acuerdo con las Reglas de Hooks , no llames hooks dentro de bucles, condiciones o funciones anidadas.
Sugiero refactorizar el useData para consumir el ID de userId como un argumento, para ser usado en la matriz de dependencias de useEffect .
const fetchData = async (userId) => { // code to fetch data from GraphQl }; const useData = (userId) => { const [data, setData] = useState(); useEffect(() => { fetchData(userId) .then((....) => { // the rest of the code to set the state variable data. }); }, [userId]); return data; };Uso en el componente Función:
const userId = useUser(); const data = useData(userId);Si esto es algo que se empareja comúnmente, resúmalo en un solo gancho:
const useGetUserData = () => { const userId = useUser(); const data = useData(userId); return data; };...
const data = useGetUserData();Aunque probablemente deberías implementarlo como un solo gancho de la siguiente manera:
const useGetUserData = () => { const [data, setData] = useState(); useEffect(() => { getUserInfo() .then(fetchData) // shortened (userId) => fetchData(userId) .then((....) => { // the rest of the code to set the state variable data. setData(....); }); }, []); return data; };No puede llamar a hook dentro de useEffect, Hook debe estar siempre dentro del cuerpo del componente, no dentro de la función interna/cuerpo del gancho.
import useUserId from "./UseUserId"; // ...rest of the necessary imports const fetchData = async (userId) => { // code to fetch data from GraphQl} }; const useData = () => { const [data, setData] = useState(); const userId = useUser(); useEffect(() => { if (userId) { fetchData(userId).then(setData); } }, [userId]); return data; };