ApolloConsumer 和缓存
ApolloConsumer and cache
我目前正在将 React 和 Graphql 与 Apollo 和 react-apollo 一起使用。
当我想从 Graphql 加载数据时,我通常使用 react-apollo 的 组件,但是如果我想在像点击这样的事件之后进行调用,据我所知,我需要用ApolloConsumer 和 client.query.
但是这样做,当更新或重置缓存时,不会更新通过 ApolloConsumer 加载的所有内容。
这是一个例子:
import React, { Component } from "react";
import { render } from "react-dom";
import ApolloClient from "apollo-boost";
import { ApolloProvider, ApolloConsumer, Query } from "react-apollo";
import gql from "graphql-tag";
const client = new ApolloClient({
uri: `https://m08pj5j9k9.lp.gql.zone/graphql`
});
class App extends Component {
state = { client: [] };
renderQuery = () => {
return (
<Query query={gql`{test01 {id, name}}`}>
{({ loading, error, data }) => {
if (loading) return "Loading...";
if (error) return "Error";
return (
<ul>
{data.test01.map(data => <li key={data.id}>{data.name}</li>)}
</ul>
);
}}
</Query>
);
};
btnQueryClick = async client => {
const data = await client.query({ query: gql`{test02 {id, name}}` });
this.setState({ client: data.data.test02 });
};
render() {
return (
<ApolloProvider client={client}>
<div>
<h2>Query test</h2>
{this.renderQuery()}
<ApolloConsumer>
{client => (
<div>
<h2>Client query test</h2>
<button onClick={() => this.btnQueryClick(client)}>
Test!
</button>
<ul>
{this.state.client.map(data => (
<li key={data.id}>{data.name}</li>
))}
</ul>
<h2>Store reset</h2>
<button
onClick={() => {
client.resetStore();
}}
>
{" "}
Reset!
</button>
</div>
)}
</ApolloConsumer>
</div>
</ApolloProvider>
);
}
}
render(<App />, document.getElementById("root"));
这里是 link 现场试用:https://codesandbox.io/s/5460952y3k
在所有请求中,我都填充了一个随机数,这样我就知道数据是否发生了变化。
如您所见,如果我按下重置按钮,"Query test" 部分中的数据将被更新,但 "Client query test" 部分中的数据不会更新。
有没有办法用 ApolloConsumer 模拟相同类型的更新?
谢谢
是的,我认为对于您的具体用例,client.query 可能不合适。这是我认为您正在寻找的代码笔:https://codesandbox.io/s/yw779qx8qv
来源:
import React, { Component } from "react";
import { render } from "react-dom";
import ApolloClient from "apollo-boost";
import { ApolloProvider, ApolloConsumer, Query } from "react-apollo";
import gql from "graphql-tag";
const client = new ApolloClient({
uri: `https://m08pj5j9k9.lp.gql.zone/graphql`
});
class App extends Component {
state = { showOtherQuery: false };
renderQuery = () => {
return (
<Query query={gql`{test01 {id, name}}`}>
{({ loading, error, data }) => {
if (loading) return "Loading...";
if (error) return "Error";
return (
<ul>
{data.test01.map(data => <li key={data.id}>{data.name}</li>)}
</ul>
);
}}
</Query>
);
};
renderOtherQuery() {
return (
<Query query={gql`{test02 {id, name}}`}>
{({ loading, error, data }) => {
if (loading) return "Loading...";
if (error) return "Error";
return (
<ul>
{data.test02.map(data => <li key={data.id}>{data.name}</li>)}
</ul>
);
}}
</Query>
);
}
render() {
return (
<ApolloProvider client={client}>
<div>
<h2>Query test</h2>
{this.renderQuery()}
<div>
<h2>Client query test</h2>
<button onClick={() => this.setState({ showOtherQuery: true })}>
Test!
</button>
{this.state.showOtherQuery && this.renderOtherQuery()}
<h2>Store reset</h2>
<button
onClick={() => {
client.resetStore();
}}
>
{" "}
Reset!
</button>
</div>
</div>
</ApolloProvider>
);
}
}
render(<App />, document.getElementById("root"));
基本上,该按钮不再使用 client.query 手动发出查询,而是设置一个布尔值来呈现一个额外的查询组件,然后当商店重置时,该组件将按照您的预期重新获取。
另一种方法是在单击重置按钮时手动调用 client.query 并再次设置状态(这基本上就是查询组件所做的)。
您不能指望手动触发的查询会自动更新。
即使重新呈现(如果它发生了,但它没有发生)消费者也不会 'refire' 事件然后没有重新查询,没有状态(和视图)更新。
查询不会创建任何类型的可观察对象 - 您可能正在寻找将手动查询与订阅相结合的方法。
为什么需要监视其他缓存更新?
尝试使用 'traditional' apollo HOCs 和 compose - 恕我直言,更具可读性、可管理性并且适用于更复杂的场景。
我目前正在将 React 和 Graphql 与 Apollo 和 react-apollo 一起使用。
当我想从 Graphql 加载数据时,我通常使用 react-apollo 的
但是这样做,当更新或重置缓存时,不会更新通过 ApolloConsumer 加载的所有内容。 这是一个例子:
import React, { Component } from "react";
import { render } from "react-dom";
import ApolloClient from "apollo-boost";
import { ApolloProvider, ApolloConsumer, Query } from "react-apollo";
import gql from "graphql-tag";
const client = new ApolloClient({
uri: `https://m08pj5j9k9.lp.gql.zone/graphql`
});
class App extends Component {
state = { client: [] };
renderQuery = () => {
return (
<Query query={gql`{test01 {id, name}}`}>
{({ loading, error, data }) => {
if (loading) return "Loading...";
if (error) return "Error";
return (
<ul>
{data.test01.map(data => <li key={data.id}>{data.name}</li>)}
</ul>
);
}}
</Query>
);
};
btnQueryClick = async client => {
const data = await client.query({ query: gql`{test02 {id, name}}` });
this.setState({ client: data.data.test02 });
};
render() {
return (
<ApolloProvider client={client}>
<div>
<h2>Query test</h2>
{this.renderQuery()}
<ApolloConsumer>
{client => (
<div>
<h2>Client query test</h2>
<button onClick={() => this.btnQueryClick(client)}>
Test!
</button>
<ul>
{this.state.client.map(data => (
<li key={data.id}>{data.name}</li>
))}
</ul>
<h2>Store reset</h2>
<button
onClick={() => {
client.resetStore();
}}
>
{" "}
Reset!
</button>
</div>
)}
</ApolloConsumer>
</div>
</ApolloProvider>
);
}
}
render(<App />, document.getElementById("root"));
这里是 link 现场试用:https://codesandbox.io/s/5460952y3k
在所有请求中,我都填充了一个随机数,这样我就知道数据是否发生了变化。 如您所见,如果我按下重置按钮,"Query test" 部分中的数据将被更新,但 "Client query test" 部分中的数据不会更新。
有没有办法用 ApolloConsumer 模拟相同类型的更新?
谢谢
是的,我认为对于您的具体用例,client.query 可能不合适。这是我认为您正在寻找的代码笔:https://codesandbox.io/s/yw779qx8qv
来源:
import React, { Component } from "react";
import { render } from "react-dom";
import ApolloClient from "apollo-boost";
import { ApolloProvider, ApolloConsumer, Query } from "react-apollo";
import gql from "graphql-tag";
const client = new ApolloClient({
uri: `https://m08pj5j9k9.lp.gql.zone/graphql`
});
class App extends Component {
state = { showOtherQuery: false };
renderQuery = () => {
return (
<Query query={gql`{test01 {id, name}}`}>
{({ loading, error, data }) => {
if (loading) return "Loading...";
if (error) return "Error";
return (
<ul>
{data.test01.map(data => <li key={data.id}>{data.name}</li>)}
</ul>
);
}}
</Query>
);
};
renderOtherQuery() {
return (
<Query query={gql`{test02 {id, name}}`}>
{({ loading, error, data }) => {
if (loading) return "Loading...";
if (error) return "Error";
return (
<ul>
{data.test02.map(data => <li key={data.id}>{data.name}</li>)}
</ul>
);
}}
</Query>
);
}
render() {
return (
<ApolloProvider client={client}>
<div>
<h2>Query test</h2>
{this.renderQuery()}
<div>
<h2>Client query test</h2>
<button onClick={() => this.setState({ showOtherQuery: true })}>
Test!
</button>
{this.state.showOtherQuery && this.renderOtherQuery()}
<h2>Store reset</h2>
<button
onClick={() => {
client.resetStore();
}}
>
{" "}
Reset!
</button>
</div>
</div>
</ApolloProvider>
);
}
}
render(<App />, document.getElementById("root"));
基本上,该按钮不再使用 client.query 手动发出查询,而是设置一个布尔值来呈现一个额外的查询组件,然后当商店重置时,该组件将按照您的预期重新获取。
另一种方法是在单击重置按钮时手动调用 client.query 并再次设置状态(这基本上就是查询组件所做的)。
您不能指望手动触发的查询会自动更新。
即使重新呈现(如果它发生了,但它没有发生)消费者也不会 'refire' 事件然后没有重新查询,没有状态(和视图)更新。
查询不会创建任何类型的可观察对象 - 您可能正在寻找将手动查询与订阅相结合的方法。
为什么需要监视其他缓存更新?
尝试使用 'traditional' apollo HOCs 和 compose - 恕我直言,更具可读性、可管理性并且适用于更复杂的场景。