admin管理员组

文章数量:1356696

I'm attempting to call a Graph QL Query after receiving data from my useEffect hook. I need the data from the response to use in the Query. Hooks however cannot be called conditionally. If I take away the condition however, loadedAnime will be undefined. How do I get around this restraint?

import React, { useEffect, useState } from "react";
import { useParams } from "react-router-dom";
import AnimeBanner from "../ponents/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;

I'm attempting to call a Graph QL Query after receiving data from my useEffect hook. I need the data from the response to use in the Query. Hooks however cannot be called conditionally. If I take away the condition however, loadedAnime will be undefined. How do I get around this restraint?

import React, { useEffect, useState } from "react";
import { useParams } from "react-router-dom";
import AnimeBanner from "../ponents/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;

Share Improve this question edited Aug 13, 2020 at 1:31 eboone20053 asked Aug 13, 2020 at 1:12 eboone20053eboone20053 651 gold badge1 silver badge8 bronze badges
Add a ment  | 

2 Answers 2

Reset to default 5

Short Answer: You can checkout useLazyQuery instead of useQuery.

Documentation link: https://www.apollographql./docs/react/data/queries/#executing-queries-manually


When React mounts and renders a ponent that calls the useQuery hook, Apollo Client automatically executes the specified query. But what if you want to execute a query in response to a different event, such as a user clicking a button?

The useLazyQuery hook is perfect for executing queries in response to events other than ponent rendering. This hook acts just like useQuery, with one key exception: when useLazyQuery is called, it does not immediately execute its associated query. Instead, it returns a function in its result tuple that you can call whenever you're ready to execute the query

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>
  );
}

You can either call the query after the await finishes or you can call your query in another useEffect once you update state after your api call. In general, something like this,

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])

or

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])

本文标签: javascriptHow to wait for server response before calling Apollo Graph QL QueryStack Overflow