web-dev-qa-db-ja.com

コンポーネントの状態の変更/再レンダリング時に `useLazyQuery`クエリが再フェッチされるのを防ぐことは可能ですか?

現在、ボタンプレス(検索フォームの一部)で発生するuseLazyQueryフックがあります。

フックは正常に動作し、ボタンが押されたときにのみ発生します。ただし、一度起動すると、コンポーネントが再レンダリングされるたびに起動されます(通常、状態の​​変化が原因です)。

したがって、一度検索してから検索フィールドを編集すると、結果がすぐに表示されるので、もう一度検索ボタンをクリックする必要はありません。

必要なUIではありません。検索テキストを完全に削除すると(nullを変数として検索しようとしているため)、エラーが発生します。useLazyQueryが再レンダリングで再フェッチされますか?

これは、ボタンをクリックしたときにトグルされる「検索」状態に依存するuseQueryを使用して回避できます。ただし、コンポーネントに複雑さを追加することを回避できるかどうかを確認します。

const AddCardSidebar = props => {
  const [searching, toggleSearching] = useState(false);
  const [searchParams, setSearchParams] = useState({
    name: ''
  });
  const [searchResults, setSearchResults] = useState([]);
  const [selectedCard, setSelectedCard] = useState();

  const [searchCardsQuery, searchCardsQueryResponse] = useLazyQuery(SEARCH_CARDS, {
    variables: { searchParams },
    onCompleted() {
      setSearchResults(searchCardsQueryResponse.data.searchCards.cards);
    }
  });

  ...

  return (
    <div>
      <h1>AddCardSidebar</h1>
      <div>
        {searchResults.length !== 0 &&
          searchResults.map(result => {
            return (
              <img
                key={result.scryfall_id}
                src={result.image_uris.small}
                alt={result.name}
                onClick={() => setSelectedCard(result.scryfall_id)}
              />
            );
          })}
      </div>
      <form>

        ...

        <button type='button' onClick={() => searchCardsQuery()}>
          Search
        </button>
      </form>

      ...

    </div>
  );
};
8
user11754604

react-apolloドキュメントには、変数が変更されてもuseLazyQueryがクエリを引き続き実行する必要があるかどうかは記載されていませんが、手動でクエリを実行する場合はuseApolloClientフックの使用を推奨しています。それら 例があります これはこの使用例に一致します(ボタンをクリックするとクエリが起動します)。

function DelayedQuery() {
  const [dog, setDog] = useState(null);
  const client = useApolloClient();

  return (
    <div>
      {dog && <img src={dog.displayImage} />}
      <button
        onClick={async () => {
          const { data } = await client.query({
            query: GET_DOG_PHOTO,
            variables: { breed: 'bulldog' },
          });
          setDog(data.dog);
        }}
      >
        Click me!
      </button>
    </div>
  );
}
8
Dylan Marshall

アポロクライアントでasyncを使用する必要はありません(使用できます)。ただし、useLazyQueryを使用する場合は、useLazyQuery呼び出しではなく、onClickで変数を渡すだけです。

上記の例では、解決策は次のようになります。

function DelayedQuery() {
  const [dog, setDog] = useState(null);
  const [getDogPhoto] = useLazyQuery(GET_DOG_PHOTO, {
    onCompleted: data => setDog(data.dog)
  })

  return (
    <div>
      {dog && <img src={dog.displayImage} />}
      <button
        onClick={() => getDogPhoto({ variables: { breed: 'bulldog' }})}
      >
        Click me!
      </button>
    </div>
  );
}
1
Yann Pravo