Actuellement, j'ai un crochet useLazyQuery
qui se déclenche en appuyant sur un bouton (partie d'un formulaire de recherche).
Le crochet se comporte normalement et ne se déclenche que lorsque le bouton est enfoncé. Cependant, une fois que je l'ai déclenché une fois, il est ensuite déclenché à chaque fois que le composant effectue un nouveau rendu (généralement en raison de changements d'état).
Donc, si je recherche une fois, puis édite les champs de recherche, les résultats apparaissent immédiatement et je n'ai pas besoin de cliquer à nouveau sur le bouton de recherche.
Pas l'interface utilisateur que je veux, et cela provoque une erreur si vous supprimez entièrement le texte de recherche (car il essaie de rechercher avec null
comme variable), existe-t-il un moyen d'empêcher le useLazyQuery
de en cours de récupération lors du re-rendu?
Cela peut être contourné en utilisant useQuery
en fonction d'un état de "recherche" qui est activé lorsque je clique sur le bouton. Cependant, je préfère voir si je peux éviter d'ajouter de la complexité au composant.
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>
);
};
Le react-apollo
la documentation ne mentionne pas si useLazyQuery
doit continuer à déclencher la requête lorsque les variables changent, mais elles suggèrent d'utiliser le hook useApolloClient
lorsque vous souhaitez déclencher manuellement une requête. Ils ont un exemple qui correspond à ce cas d'utilisation (cliquer sur un bouton déclenche la requête).
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>
);
}
Vous n'avez pas besoin d'utiliser async
avec le client apollo (vous pouvez, cela fonctionne). Mais si vous voulez utiliser useLazyQuery
, il vous suffit de passer des variables sur onClick
et non directement sur l'appel useLazyQuery.
Avec l'exemple ci-dessus, la solution serait:
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>
);
}