如何在调用 Apollo Graphql Query 之前等待服务器响应?
How to wait for server response before calling Apollo Graph QL Query?
我试图在从我的 useEffect 挂钩接收数据后调用 Graph QL 查询。我需要响应中的数据才能在查询中使用。但是不能有条件地调用钩子。但是,如果我取消条件,loadedAnime 将是未定义的。我该如何绕过这种限制?
import React, { useEffect, useState } from "react";
import { useParams } from "react-router-dom";
import AnimeBanner from "../components/AnimeBanner";
import { useHttpClient } from "../Hooks/http-hook";
import { GetAnimeData } from "../GraphQLFunctions";
import { useQuery } from "@apollo/react-hooks";
import gql from "graphql-tag";
const GET_ANIME_INFO = gql`
query GetAnimeInfo($name: String!) {
Media(search: $name) {
title {
romaji
english
native
userPreferred
}
episodes
id
bannerImage
}
}
`;
const Anime = (props) => {
//Logic for getting anime data from mongoDB (episodes, name, cover image)
const { isLoading, error, sendRequest } = useHttpClient();
const [loadedAnime, setloadedAnime] = useState();
const URLTitle = useParams().URLTitle;
useEffect(() => {
const fetchAnime = async () => {
try {
const responseData = await sendRequest(
"http://localhost:5000/api/anime/" + URLTitle
);
setloadedAnime(responseData.animeData[0]);
} catch (err) {
console.log(err);
}
};
fetchAnime();
}, [sendRequest, URLTitle]);
if (isLoading || error) {
return null;
}
//Logic for getting anime data from anilist (Descriptions, tags, banner, trailer, etc.)
const { apiData, apiLoading, apiError } = useQuery(GET_ANIME_INFO, {
variables: {
name: loadedAnime.anime_name,
},
});
if (apiLoading || apiError) {
return null;
}
return <AnimeBanner src={apiData.Media.bannerImage} />;
};
export default Anime;
您可以在 await
完成后调用查询,也可以在 api 调用后更新状态后在另一个 useEffect
中调用查询。一般来说,像这样,
const [state, setState] = useState({})
useEffect(async () => {
const result = await get('/api/blah-blah-blah')
// run your query here now that the await has resolved
}, [someDependency])
或
const [state, setState] = useState({})
useEffect(async () => {
const result = await get('/api/blah-blah-blah')
setState(result)
}, [someDependency])
useEffect(() => {
if(state.id) {
// run the query
}
}, [state.someProp])
简答:您可以使用 useLazyQuery 而不是 useQuery。
文档 link:https://www.apollographql.com/docs/react/data/queries/#executing-queries-manually
当React 挂载并渲染调用useQuery 钩子的组件时,Apollo Client 会自动执行指定的查询。但是,如果您想执行查询以响应不同的事件(例如用户单击按钮)怎么办?
useLazyQuery 挂钩非常适合执行查询以响应组件呈现以外的事件。这个钩子就像 useQuery 一样,有一个关键的例外:调用 useLazyQuery 时,它不会立即执行其关联的查询。相反,它 returns 结果元组中的一个函数,您可以在准备好执行查询时调用该函数
import React, { useState } from 'react';
import { useLazyQuery } from '@apollo/client';
function DelayedQuery() {
const [dog, setDog] = useState(null);
const [getDog, { loading, data }] = useLazyQuery(GET_DOG_PHOTO);
if (loading) return <p>Loading ...</p>;
if (data && data.dog) {
setDog(data.dog);
}
return (
<div>
{dog && <img src={dog.displayImage} />}
<button onClick={() => getDog({ variables: { breed: 'bulldog' } })}>
Click me!
</button>
</div>
);
}
我试图在从我的 useEffect 挂钩接收数据后调用 Graph QL 查询。我需要响应中的数据才能在查询中使用。但是不能有条件地调用钩子。但是,如果我取消条件,loadedAnime 将是未定义的。我该如何绕过这种限制?
import React, { useEffect, useState } from "react";
import { useParams } from "react-router-dom";
import AnimeBanner from "../components/AnimeBanner";
import { useHttpClient } from "../Hooks/http-hook";
import { GetAnimeData } from "../GraphQLFunctions";
import { useQuery } from "@apollo/react-hooks";
import gql from "graphql-tag";
const GET_ANIME_INFO = gql`
query GetAnimeInfo($name: String!) {
Media(search: $name) {
title {
romaji
english
native
userPreferred
}
episodes
id
bannerImage
}
}
`;
const Anime = (props) => {
//Logic for getting anime data from mongoDB (episodes, name, cover image)
const { isLoading, error, sendRequest } = useHttpClient();
const [loadedAnime, setloadedAnime] = useState();
const URLTitle = useParams().URLTitle;
useEffect(() => {
const fetchAnime = async () => {
try {
const responseData = await sendRequest(
"http://localhost:5000/api/anime/" + URLTitle
);
setloadedAnime(responseData.animeData[0]);
} catch (err) {
console.log(err);
}
};
fetchAnime();
}, [sendRequest, URLTitle]);
if (isLoading || error) {
return null;
}
//Logic for getting anime data from anilist (Descriptions, tags, banner, trailer, etc.)
const { apiData, apiLoading, apiError } = useQuery(GET_ANIME_INFO, {
variables: {
name: loadedAnime.anime_name,
},
});
if (apiLoading || apiError) {
return null;
}
return <AnimeBanner src={apiData.Media.bannerImage} />;
};
export default Anime;
您可以在 await
完成后调用查询,也可以在 api 调用后更新状态后在另一个 useEffect
中调用查询。一般来说,像这样,
const [state, setState] = useState({})
useEffect(async () => {
const result = await get('/api/blah-blah-blah')
// run your query here now that the await has resolved
}, [someDependency])
或
const [state, setState] = useState({})
useEffect(async () => {
const result = await get('/api/blah-blah-blah')
setState(result)
}, [someDependency])
useEffect(() => {
if(state.id) {
// run the query
}
}, [state.someProp])
简答:您可以使用 useLazyQuery 而不是 useQuery。
文档 link:https://www.apollographql.com/docs/react/data/queries/#executing-queries-manually
当React 挂载并渲染调用useQuery 钩子的组件时,Apollo Client 会自动执行指定的查询。但是,如果您想执行查询以响应不同的事件(例如用户单击按钮)怎么办?
useLazyQuery 挂钩非常适合执行查询以响应组件呈现以外的事件。这个钩子就像 useQuery 一样,有一个关键的例外:调用 useLazyQuery 时,它不会立即执行其关联的查询。相反,它 returns 结果元组中的一个函数,您可以在准备好执行查询时调用该函数
import React, { useState } from 'react';
import { useLazyQuery } from '@apollo/client';
function DelayedQuery() {
const [dog, setDog] = useState(null);
const [getDog, { loading, data }] = useLazyQuery(GET_DOG_PHOTO);
if (loading) return <p>Loading ...</p>;
if (data && data.dog) {
setDog(data.dog);
}
return (
<div>
{dog && <img src={dog.displayImage} />}
<button onClick={() => getDog({ variables: { breed: 'bulldog' } })}>
Click me!
</button>
</div>
);
}