Maison  >  Questions et réponses  >  le corps du texte

Revalider après mutation dans une requête de réaction : guide étape par étape

J'ai implémenté l'implémentation de base de la récupération et de la mise à jour des données à l'aide de react-query sur une application next.js. Mon objectif est de mettre à jour les données après mutation. Actuellement, les données ne sont mises à jour que lorsque l'onglet est actualisé. Mais cela ne changera pas sans l’interaction de l’utilisateur.

J'ai trouvé que la mise à jour des données lors de l'actualisation de l'onglet est due au comportement par défaut de refetchOnWindowFocus.

Mais comment devient-il invalide une fois les données mises à jour côté serveur ? Voici l'extrait de code correspondant.

Remarque : J'utilise Hydration pour utiliser la fonctionnalité react-query SSR. Documentation

_app.jsx

const [queryClient] = React.useState(() => new QueryClient());

  return (
    <QueryClientProvider client={queryClient}>
      <Hydrate state={pageProps.dehydratedState}>
          <Component {...pageProps} />
      </Hydrate>
    </QueryClientProvider>

Accueil.jsx

const {data} = useQuery({
    queryKey: [queryKeys.key],
    queryFn: fetchData,
    staleTime: 1000 * 10, // this doesn't affect on anything
    //refetchInterval: 2000, this updates every 2 seconds
  });

  return (
    <div>
      <Article articles={data} />
    </div>
  );
   export const getServerSideProps = async () => {
  const queryClient = new QueryClient();
  await queryClient.prefetchQuery([queryKeys.key], fetchData);
  return { props: { dehydratedState: dehydrate(queryClient) } };
};

article.jsx

const Article = ({articles}) => {
  const [title, setTitle] = useState("");
  const queryClient = new QueryClient();

  const { mutate } = useMutation({
    mutationFn: async (article) => {
      return await axios.post(url, article);
    },
    onSuccess: (data) => {
      console.log("data", data) // data is displayed, onSuccess is called
      queryClient.invalidateQueries({ queryKey: [queryKeys.key] });
    },
  });

  const changeTitleHandleClick = () => {
    mutate({
      id: new Date(),
      title: title
    });
    setTitle("");
  };
  ....

Toute aide serait grandement appréciée

Mises à jour : refetchInterval:2000 se met à jour toutes les 2 secondes, mais cela déclenche une requête réseau toutes les 2 secondes, donc je ne suis pas sûr que ce soit une bonne pratique pour la revalidation.

Mise à jour : onSuccess方法内的控制台在突变时显示,这意味着逻辑有问题,因为即使密钥不同,这也应该有效:queryClient.invalidateQueries() où je ne spécifie aucune clé mais déclenche toutes les requêtes. Mais même dans ce cas, il ne sera pas mis à jour. Pourquoi?

P粉752290033P粉752290033230 Il y a quelques jours406

répondre à tous(2)je répondrai

  • P粉677684876

    P粉6776848762024-03-26 11:50:35

    De la façon dont vous implémentez la mutation, la requête doit être récupérée après une mutation réussie :

    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: [queryKeys.key] });
    },

    Si cela ne fonctionne pas, votre mutation a échoué. Vérifiez si le rappel onSuccess est appelé.

    Si le rappel onSuccess 回调,但未重新提取您的查询,则可能意味着 queryKey est appelé, mais que votre requête n'est pas récupérée, cela peut signifier une incompatibilité

    . À des fins de test, essayez d'étendre le filtre à :

    queryClient.invalidateQueries()
    devrait récupérer toutes les queryKeyrequêtes. Si cela fonctionne, vous savez que votre filtre

    ne correspond pas.

    Regardez bien, vous échouez :

    queryKey: [queryKeys.key]

    Mais dans votre hook personnalisé, vous utilisez :

    queryKey: [queryKeys.articles]
    @tanstack/react-query-devtoolsIl semble donc qu’ils soient effectivement différents et donc ne correspondent pas. Assurez-vous également d'utiliser

    pour mieux comprendre les requêtes et les clés dans le cache. 🎜

    répondre
    0
  • P粉231079976

    P粉2310799762024-03-26 11:47:03

    Le problème est que dans le composant Article.jsx je crée un nouveau QueryClient à chaque rendu, il obtient donc un nouveau cache et n'est donc pas mis à jour.
    Au lieu de cela, je dois utiliser le hook useQueryClient, qui renvoie l'instance actuelle.
    const queryClient = useQueryClient();

    répondre
    0
  • Annulerrépondre