"Error: invalid hook call" When using the hook within a function called on click of a button
"Error: invalid hook call" When using the hook within a function called on click of a button
我有一个组件,它具有关注和取消关注人员的逻辑。单击按钮时,应调用包含查询逻辑的函数。但是当我按下按钮时,它给我“错误:无效的钩子调用,钩子并且只能在函数组件的主体内部调用”
这些是我用于关注和取消关注逻辑的 2 个函数:
function onFollowingClick() {
const {isLoading: deleteFollowerLoading} = useQuery(["deleteFollower", myFollowerId], () => {
deleteFollower(myFollowerId)
})
console.log("following call")
}
function onFollowClick() {
const {isLoading:createFollowerLoading} = useQuery("createFollower",
createFollower()
)
console.log("follower call")
}
这是我调用函数的按钮,在map函数里面,你可以在onclick中看到:
return (
<div className={root}>
<div className={body}>
{
myFollowers && myFollowings && !followerLoading && (
followersData.map((e) => {
return(<>
<div className="data">
<Grid templateColumns="repeat(2, 1fr)" width="100%" alignContent="center">
<GridItem w="100%" >
<Flex
mt="10px">
<Avatar
size={isTabletOrMobile ? "xs" : "sm"}
src={e.requested_profile.s3PicURL}
/>
<Text
w="100%"
wrap="off"
ml="5px"
isTruncated
fontSize={isTabletOrMobile ? "sm" : "md"}
>
{e.requested_profile.Userlink}
</Text>
</Flex>
</GridItem>
<GridItem>
<Flex justifyContent="flex-end">
<Button
w="100px"
h="30px"
mt="8px"
onClick = { () => {
if(myFollowings.includes(e.requested_profile.Userlink)){
onFollowingClick()
}
else{
onFollowClick()
}
} }
variant={myFollowings.includes(e.requested_profile.Userlink) ? "outline" : "solid"}
width={isTabletOrMobile ? "50px" : "60px"}>
{
myFollowings.includes(e.requested_profile.Userlink) ? "Following" : "Follow"
}
</Button>
</Flex>
</GridItem>
</Grid>
</div>
</>
)
})
)
}
</div>
</div>
)
请告诉我如何解决这个错误。
这里有几个问题:
你不能在任何地方使用挂钩,除非它在顶级组件级别 (https://reactjs.org/docs/hooks-overview.html#rules-of-hooks)。
您使用 react-query
并尝试使用 useQuery
改变状态。该钩子用于获取数据。如果你想做突变,你应该使用 useMutation
钩子。但请注意,这些挂钩也应该位于顶层,您不能像我们调用常规函数那样从点击处理程序调用它。
那么,您的步骤是:
- 使用回调和后端交互逻辑定义
useMutation
挂钩
- 当你点击按钮时你调用
mutationFollow.mutate({ id: item.id })
- 要在突变后使您的状态无效,您应该使用
onSuccess
回调:
onSuccess: () => {
queryClient.invalidateQueries('followers')
},
执行您想要的操作的选项之一可能是:
const queryClient = useQueryClient()
const Component = () => {
const { isLoading, data: followers } = useQuery('followers')
const mutationFollow = useMutation(
follower => {
return axios.post('/follow', follower)
},
{
onSuccess: () => {
queryClient.invalidateQueries('followers')
},
},
)
const mutationUnfollow = useMutation(
follower => {
return axios.post('/unfollow', follower)
},
{
onSuccess: () => {
queryClient.invalidateQueries('followers')
},
},
)
if (isLoading) {
return <div>Loading...</div>
}
return followers.map(item => (
<div>
<button
onClick={() => {
mutationFollow.mutate({ id: item.id })
}}
>
Follow
</button>
<button
onClick={() => {
mutationUnfollow.mutate({ id: item.id })
}}
>
Unfollow
</button>
</div>
))
}
我有一个组件,它具有关注和取消关注人员的逻辑。单击按钮时,应调用包含查询逻辑的函数。但是当我按下按钮时,它给我“错误:无效的钩子调用,钩子并且只能在函数组件的主体内部调用”
这些是我用于关注和取消关注逻辑的 2 个函数:
function onFollowingClick() {
const {isLoading: deleteFollowerLoading} = useQuery(["deleteFollower", myFollowerId], () => {
deleteFollower(myFollowerId)
})
console.log("following call")
}
function onFollowClick() {
const {isLoading:createFollowerLoading} = useQuery("createFollower",
createFollower()
)
console.log("follower call")
}
这是我调用函数的按钮,在map函数里面,你可以在onclick中看到:
return (
<div className={root}>
<div className={body}>
{
myFollowers && myFollowings && !followerLoading && (
followersData.map((e) => {
return(<>
<div className="data">
<Grid templateColumns="repeat(2, 1fr)" width="100%" alignContent="center">
<GridItem w="100%" >
<Flex
mt="10px">
<Avatar
size={isTabletOrMobile ? "xs" : "sm"}
src={e.requested_profile.s3PicURL}
/>
<Text
w="100%"
wrap="off"
ml="5px"
isTruncated
fontSize={isTabletOrMobile ? "sm" : "md"}
>
{e.requested_profile.Userlink}
</Text>
</Flex>
</GridItem>
<GridItem>
<Flex justifyContent="flex-end">
<Button
w="100px"
h="30px"
mt="8px"
onClick = { () => {
if(myFollowings.includes(e.requested_profile.Userlink)){
onFollowingClick()
}
else{
onFollowClick()
}
} }
variant={myFollowings.includes(e.requested_profile.Userlink) ? "outline" : "solid"}
width={isTabletOrMobile ? "50px" : "60px"}>
{
myFollowings.includes(e.requested_profile.Userlink) ? "Following" : "Follow"
}
</Button>
</Flex>
</GridItem>
</Grid>
</div>
</>
)
})
)
}
</div>
</div>
)
请告诉我如何解决这个错误。
这里有几个问题:
你不能在任何地方使用挂钩,除非它在顶级组件级别 (https://reactjs.org/docs/hooks-overview.html#rules-of-hooks)。
您使用
react-query
并尝试使用useQuery
改变状态。该钩子用于获取数据。如果你想做突变,你应该使用useMutation
钩子。但请注意,这些挂钩也应该位于顶层,您不能像我们调用常规函数那样从点击处理程序调用它。
那么,您的步骤是:
- 使用回调和后端交互逻辑定义
useMutation
挂钩 - 当你点击按钮时你调用
mutationFollow.mutate({ id: item.id })
- 要在突变后使您的状态无效,您应该使用
onSuccess
回调:
onSuccess: () => {
queryClient.invalidateQueries('followers')
},
执行您想要的操作的选项之一可能是:
const queryClient = useQueryClient()
const Component = () => {
const { isLoading, data: followers } = useQuery('followers')
const mutationFollow = useMutation(
follower => {
return axios.post('/follow', follower)
},
{
onSuccess: () => {
queryClient.invalidateQueries('followers')
},
},
)
const mutationUnfollow = useMutation(
follower => {
return axios.post('/unfollow', follower)
},
{
onSuccess: () => {
queryClient.invalidateQueries('followers')
},
},
)
if (isLoading) {
return <div>Loading...</div>
}
return followers.map(item => (
<div>
<button
onClick={() => {
mutationFollow.mutate({ id: item.id })
}}
>
Follow
</button>
<button
onClick={() => {
mutationUnfollow.mutate({ id: item.id })
}}
>
Unfollow
</button>
</div>
))
}