[英]How to use a custom-hook that returns a value, inside another custom Hook?
I am using React-native and in it, I have a custom Hook called useUser
that gets the user's information from AWS Amplify using the Auth.getUserInfro
method, and then gets part of the returned object and sets a state variable with it.我正在使用 React-native,在其中,我有一个名为
useUser
的自定义 Hook,它使用Auth.getUserInfro
方法从 AWS Amplify 获取用户信息,然后获取返回的 object 的一部分,并使用它设置一个 Z9ED39E25EA931586B76E9 变量。 I also have another Hook called useData
hook that fetches some data based on the userId and sets it to a state variable.我还有另一个名为
useData
的 Hook,它根据 userId 获取一些数据并将其设置为 state 变量。
useUser custom-Hook:使用用户自定义-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
}
When I try to do this I get an error telling me当我尝试这样做时,我收到一条错误消息告诉我
*Error: Invalid hook call. *错误:无效的挂钩调用。 Hooks can only be called inside of the body of a function component.
钩子只能在 function 组件的主体内部调用。 This could happen for one of the following reasons:
这可能由于以下原因之一而发生:
I think the problem is that I am calling the Hook useUser inside of the use effect, but using it inside the function will cause the problem described here , and I can't use it outside the body of the fetchData
since the useData
itself is a hook, and it can be only used inside a functional component's or Hook's body.我认为问题在于我在 use 效果内部调用了 Hook useUser,但是在 function 内部使用它会导致这里描述的问题,并且我不能在
fetchData
的主体之外使用它,因为useData
本身是一个hook,只能在函数式组件或 Hook 体内使用。 So I don't know how to find a way around this problem.所以我不知道如何找到解决这个问题的方法。
Correct, React hooks can only be called from React function components and other React hooks.正确,React 钩子只能从 React function 组件和其他 React 钩子中调用。 The
useEffect
hook's callback isn't a React hook, it's a callback. useEffect
钩子的回调不是 React 钩子,它是一个回调。 According to the Rules of Hooks , don't call hooks inside loops, conditions, or nested functions.根据钩子规则,不要在循环、条件或嵌套函数中调用钩子。
I suggest refactoring the useData
hook to consume the userId
as an argument, to be used in the dependency array of the useEffect
.我建议重构
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;
};
Usage in Function component: Function 组件中的用法:
const userId = useUser();
const data = useData(userId);
If this is something that is commonly paired, abstract into a single hook:如果这是通常配对的东西,请抽象成一个钩子:
const useGetUserData = () => {
const userId = useUser();
const data = useData(userId);
return data;
};
... ...
const data = useGetUserData();
Though you should probably just implement as a single hook as follows:尽管您可能应该将其实现为单个钩子,如下所示:
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;
};
You can't call hook inside useEffect, Hook should be always inside componet body not inside inner function/hook body.你不能在 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;
};
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.