現在、ボタンプレス(検索フォームの一部)で発生する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>
);
};
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>
);
}
アポロクライアントで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>
);
}