为了账号安全,请及时绑定邮箱和手机立即绑定

如何在调用 Apollo Graph QL Query 之前等待服务器响应?

如何在调用 Apollo Graph QL Query 之前等待服务器响应?

吃鸡游戏 2023-01-06 11:02:36

从我的 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;


查看完整描述

2 回答

?
慕森卡

TA贡献1556条经验 获得超8个赞

简短回答:您可以签出 useLazyQuery 而不是 useQuery。

文档链接:https ://www.apollographql.com/docs/react/data/queries/#executing-queries-manually


当 React 挂载并渲染调用 useQuery 钩子的组件时,Apollo Client 会自动执行指定的查询。但是,如果您想要执行查询以响应不同的事件(例如用户单击按钮)怎么办?

useLazyQuery 挂钩非常适合执行查询以响应组件呈现以外的事件。这个钩子就像 useQuery 一样,有一个关键的例外:调用 useLazyQuery 时,它不会立即执行其关联的查询。相反,它在其结果元组中返回一个函数,您可以在准备好执行查询时调用该函数

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>

  );

}


查看完整回答
反对 回复 2023-01-06
?
跃然一笑

TA贡献1566条经验 获得超6个赞

您可以在完成后调用查询,也可以在 api 调用后更新状态后调用await另一个查询。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])


查看完整回答
反对 回复 2023-01-06
  • 2 回答
  • 0 关注
  • 8 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信