使用 Apollo Client 在 ReactJs 中的组件之间发送数据
Send data between components in ReactJs using Apollo Client
根据文档,GraphQl 提供像 Redux 一样的状态管理。我有 2 个组件。在 Component1
中,我使用 AppoloClient 从服务器获取数据,它工作正常,在 Component2
中,我想从 cache
(存储)读取数据。
//Component1
import React from "react";
import { gql, useQuery } from "@apollo/client";
const EXCHANGE_RATES = gql`
query GetExchangeRates {
rates(currency: "EUR") {
currency
}
}
`;
const Component1 = () => {
const { loading, error, data } = useQuery(EXCHANGE_RATES);
console.log("component1", data);
return <div>Component1</div>;
};
export default Component1;
//Component2
import React from 'react';
import {gql} from "@apollo/client";
import {client} from "./App";
const Component2 = () => {
const info = client.readQuery({
query: gql`
query EXCHANGE_RATES {
rates(currency: "EUR") {
currency
}
}
`,
});
console.log('component2',info);
return (
<div>
component2
</div>
);
};
export default Component2;
问题:我可以在组件 1 中获取数据,但是当我尝试从组件 2 中读取数据时,我得到 undefined
。
问题:如何解决这个问题,以便能够读取在组件 1 和组件 2 中获取的数据?另外,如何在 GraphQl 和 Apollo 客户端中传递缓存中的对象,并在组件 1 中读取它(如 redux 功能)?
演示:https://codesandbox.io/s/empty-sun-symv6?file=/src/App.js
Apollo 提供客户端端状态处理,可以设置为处理您的客户端站点状态,就像我们做的那样使用您的服务器端状态。
在您的示例中,这不是您想要的。最近 React 社区有一个明显的转变,即服务器端数据不应存储在您选择的全局状态处理工具中。你的抓取工具(在你的例子中是 apollo)应该通过缓存响应来处理这个问题。
要解决您的问题,即两个组件都使用完全相同的查询,您应该这样做。 运行 查询两次,让 apollo 处理缓存。因此,您可以将查询提取到查询文件中,或者只创建一个 useRates 挂钩并将其导入您的组件,以更好地在您的组件之间共享逻辑。
要回答为什么你的方法不起作用,你必须明白你在缓存中的查找是在你的请求完成之前的某个时间发生的,并且这个缓存查找不是“反应性的”。
编辑:我只是快速完成它以提供一个起点,如果事情得到解决,可以稍后清理它。
当 App 安装时,您的两个组件的数据都是空的。
然后 apollo 使用 useQuery 获取数据。并且您的 component1 的状态发生了变化。因此,component1 重新渲染并记录新数据。
但是您的 component2 上没有状态发生变化。因此,component2 不会重新渲染。
为了解决这个问题,你可以 运行 useQuery hook 再次在 component2 上使用相同的查询,默认情况下 apollo 会为你提供缓存中的数据。
根据文档,GraphQl 提供像 Redux 一样的状态管理。我有 2 个组件。在 Component1
中,我使用 AppoloClient 从服务器获取数据,它工作正常,在 Component2
中,我想从 cache
(存储)读取数据。
//Component1
import React from "react";
import { gql, useQuery } from "@apollo/client";
const EXCHANGE_RATES = gql`
query GetExchangeRates {
rates(currency: "EUR") {
currency
}
}
`;
const Component1 = () => {
const { loading, error, data } = useQuery(EXCHANGE_RATES);
console.log("component1", data);
return <div>Component1</div>;
};
export default Component1;
//Component2
import React from 'react';
import {gql} from "@apollo/client";
import {client} from "./App";
const Component2 = () => {
const info = client.readQuery({
query: gql`
query EXCHANGE_RATES {
rates(currency: "EUR") {
currency
}
}
`,
});
console.log('component2',info);
return (
<div>
component2
</div>
);
};
export default Component2;
问题:我可以在组件 1 中获取数据,但是当我尝试从组件 2 中读取数据时,我得到 undefined
。
问题:如何解决这个问题,以便能够读取在组件 1 和组件 2 中获取的数据?另外,如何在 GraphQl 和 Apollo 客户端中传递缓存中的对象,并在组件 1 中读取它(如 redux 功能)?
演示:https://codesandbox.io/s/empty-sun-symv6?file=/src/App.js
Apollo 提供客户端端状态处理,可以设置为处理您的客户端站点状态,就像我们做的那样使用您的服务器端状态。
在您的示例中,这不是您想要的。最近 React 社区有一个明显的转变,即服务器端数据不应存储在您选择的全局状态处理工具中。你的抓取工具(在你的例子中是 apollo)应该通过缓存响应来处理这个问题。
要解决您的问题,即两个组件都使用完全相同的查询,您应该这样做。 运行 查询两次,让 apollo 处理缓存。因此,您可以将查询提取到查询文件中,或者只创建一个 useRates 挂钩并将其导入您的组件,以更好地在您的组件之间共享逻辑。
要回答为什么你的方法不起作用,你必须明白你在缓存中的查找是在你的请求完成之前的某个时间发生的,并且这个缓存查找不是“反应性的”。
编辑:我只是快速完成它以提供一个起点,如果事情得到解决,可以稍后清理它。
当 App 安装时,您的两个组件的数据都是空的。
然后 apollo 使用 useQuery 获取数据。并且您的 component1 的状态发生了变化。因此,component1 重新渲染并记录新数据。
但是您的 component2 上没有状态发生变化。因此,component2 不会重新渲染。
为了解决这个问题,你可以 运行 useQuery hook 再次在 component2 上使用相同的查询,默认情况下 apollo 会为你提供缓存中的数据。