如何在另一个自定义 Hook 中使用返回值的自定义钩子?



我正在使用 React-native,在其中,我有一个名为useUser的自定义 Hook,它使用Auth.getUserInfro方法从 AWS Amplify 获取用户的信息,然后获取返回对象的一部分并使用它设置状态变量。我还有另一个名为useDatahook 的 Hook,它根据 userId 获取一些数据并将其设置为状态变量。

使用用户自定义钩子:

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
}

当我尝试执行此操作时,我收到一个错误,告诉我

*错误:无效的挂钩调用。钩子只能在函数组件的主体内部调用。这可能是由于以下原因之一而发生的:

  1. 你可能有不匹配的 React 和渲染器版本(例如 React DOM)
  2. 你可能违反了钩子的规则
  3. 您可能在同一应用程序中有多个 React 副本 有关如何调试和解决此问题的提示,请参阅 https://reactjs.org/link/invalid-hook-call。

我认为问题是我在使用效果内部调用 Hook useUser,但在函数内部使用它会导致这里描述的问题,并且我不能在fetchData体之外使用它,因为useData本身就是一个钩子,它只能在功能组件或 Hook 的主体内部使用。所以我不知道如何找到解决这个问题的方法。

没错,React 钩子只能从 React 函数组件和其他 React 钩子中调用。useEffect钩子的回调不是 React 钩子,而是回调。根据钩子规则,不要在循环、条件或嵌套函数中调用钩子。

我建议重构useData钩子以将userId用作参数,以用于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;
};

函数组件中的用法:

const userId = useUser();
const data = useData(userId);

如果这是通常配对的东西,请抽象成一个钩子:

const useGetUserData = () => {
const userId = useUser();
const data = useData(userId);
return data;
};

const data = useGetUserData();

尽管您可能应该仅作为单个钩子实现,如下所示:

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;
};

你不能在 useEffect 中调用钩子,钩子应该总是在组件体内,而不是在内部函数/钩子体内。

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;
};

相关内容

  • 没有找到相关文章

最新更新