You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在React-Query的独立组件中访问mutate返回的数据?

如何在独立组件中获取React Query mutation的状态数据

我们可以在不同组件中通过引用相同的queryKey,从多个useQuery方法中获取数据。现在需要了解如何在独立组件中,获取由其他组件执行的mutation的success、error、data等状态数据。

执行mutate的组件

import React, { useState, useRef } from "react";

import "./App.scss";

import { postNutritionix } from "../apis/postNutritionix";
import { useMutation } from "@tanstack/react-query";

const CompPostGetData = () => {
  const refQuery = useRef(null);
  const refApiId = useRef(null);
  const refApiKey = useRef(null);

  const { error: errorMutate, mutate, data: respMutate } = useMutation({
    mutationFn: postNutritionix,
    onSuccess: (resp) => {
      console.log(resp);
    }
  });

  const handleSubmitQuery = (evt) => {
    mutate({
      apiId: refApiId.current.value,
      apiKey: refApiKey.current.value,
      query: refQuery.current.value
    });
    evt.preventDefault();
  };

  const errorMessage = errorMutate?.response?.data?.message;

  const foodNutrients = respMutate?.data?.foods?.[0] || {};

  console.log(foodNutrients);
  return (
    <section>
      <article>
        <form onSubmit={handleSubmitQuery}>
          <ul>
            <li>
              <label>
                Food: <input type="text" ref={refQuery} />
              </label>
            </li>
            <li>
              <label>
                apiId:
                <input type="password" ref={refApiId} />
              </label>
            </li>
            <li>
              <label>
                apiKey:
                <input type="password" ref={refApiKey} />
              </label>
            </li>
          </ul>
          <button type="submit">Submit query</button>

          {errorMutate ? (
            <div className="error">Error: {errorMessage}</div>
          ) : null}
        </form>
      </article>
    </section>
  );
};

获取mutate数据的组件

const CompGetFromMutateData = () => {
  // 如何从其他组件执行的mutate中获取数据
  // const {data} = useMutation({
  // queryKey here???
  // });
};

解决方案

React Query的mutation本身没有queryKey,要跨组件共享mutation状态,推荐两种实用方式:

方式一:利用QueryClient缓存关联queryKey

在mutation执行成功后,将结果存入指定queryKey的缓存,其他组件通过useQuery监听该queryKey获取数据。

  1. 修改执行mutate的组件:
import { useMutation, useQueryClient } from '@tanstack/react-query';

const CompPostGetData = () => {
  const queryClient = useQueryClient();
  const refQuery = useRef(null);
  const refApiId = useRef(null);
  const refApiKey = useRef(null);

  const { error: errorMutate, mutate, data: respMutate } = useMutation({
    mutationFn: postNutritionix,
    onSuccess: (resp) => {
      // 将mutation结果存入指定queryKey的缓存
      queryClient.setQueryData(['nutritionixData'], resp);
    }
  });

  // 其余代码保持不变
};
  1. 修改获取数据的组件:
import { useQuery } from '@tanstack/react-query';

const CompGetFromMutateData = () => {
  // 通过相同queryKey获取缓存中的mutation数据
  const { data, error, isSuccess } = useQuery({
    queryKey: ['nutritionixData'],
    enabled: false, // 禁止自动触发查询,仅读取缓存
    queryFn: () => Promise.resolve(null) // 空查询函数,因为我们用缓存数据
  });

  return (
    <section>
      {isSuccess && data ? (
        <div>
          <h3>营养数据</h3>
          <p>食物名称: {data.data.foods[0]?.food_name}</p>
          <p>卡路里: {data.data.foods[0]?.nf_calories}</p>
        </div>
      ) : error ? (
        <div className="error">错误: {error.response?.data?.message}</div>
      ) : null}
    </section>
  );
};

方式二:通过Context共享mutation实例

创建React Context,将mutation的状态和方法放入Context,让子组件通过useContext直接获取。

  1. 创建Context和自定义Hook:
import { createContext, useContext } from 'react';
import { useMutation } from '@tanstack/react-query';
import { postNutritionix } from "../apis/postNutritionix";

const NutritionixMutationContext = createContext(null);

export const NutritionixMutationProvider = ({ children }) => {
  const mutation = useMutation({
    mutationFn: postNutritionix,
    onSuccess: (resp) => {
      console.log(resp);
    }
  });

  return (
    <NutritionixMutationContext.Provider value={mutation}>
      {children}
    </NutritionixMutationContext.Provider>
  );
};

export const useNutritionixMutation = () => useContext(NutritionixMutationContext);
  1. 在父组件中包裹Provider:
// 父组件示例
import { NutritionixMutationProvider } from './path-to-context';

function App() {
  return (
    <NutritionixMutationProvider>
      <CompPostGetData />
      <CompGetFromMutateData />
    </NutritionixMutationProvider>
  );
}
  1. 修改执行mutate的组件:
import { useNutritionixMutation } from './path-to-context';

const CompPostGetData = () => {
  const refQuery = useRef(null);
  const refApiId = useRef(null);
  const refApiKey = useRef(null);
  // 从Context获取mutation实例
  const { mutate, error: errorMutate, data: respMutate } = useNutritionixMutation();

  // 其余代码保持不变
};
  1. 修改获取数据的组件:
import { useNutritionixMutation } from './path-to-context';

const CompGetFromMutateData = () => {
  const { data, error, isSuccess } = useNutritionixMutation();

  return (
    <section>
      {isSuccess && data ? (
        <div>
          <h3>营养数据</h3>
          <p>食物名称: {data.data.foods[0]?.food_name}</p>
          <p>卡路里: {data.data.foods[0]?.nf_calories}</p>
        </div>
      ) : error ? (
        <div className="error">错误: {error.response?.data?.message}</div>
      ) : null}
    </section>
  );
};

内容的提问来源于stack exchange,提问作者steve

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.13 05:37:33