#javascript #reactjs #react-query
#javascript #reactjs #реакция-запрос
Вопрос:
У меня есть компонент, который имеет логику для следования и отмены подписки на людей. При нажатии кнопки должна вызываться функция, которая включает логику запроса. Но когда я нажимаю кнопку, это выдает мне «ошибка: недопустимый вызов перехвата, перехваты и вызываются только внутри тела функционального компонента»
Это мои 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 amp;amp; myFollowings amp;amp; !followerLoading amp;amp; (
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>
)
пожалуйста, скажите мне, как мне решить эту ошибку.
Ответ №1:
Здесь есть несколько проблем:
- Вы не можете использовать крючки где угодно, если только они не находятся на уровне верхнего компонента (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>
))
}