【发布时间】:2018-09-23 07:03:07
【问题描述】:
我一直在尝试使用从我的服务器重新获取的最新数据来更新我的缓存,但由于某种原因,我所有的旧数据都会一直保留,直到我重新启动服务器或执行类似 client.resetStore() 之类的操作。
当我第一次启动我的应用程序时,它会在客户端缓存中存储一封电子邮件。然后使用这个缓存的电子邮件,它被传递到服务器端查询以获取有关用户的数据。然后我通过 props 访问这些数据并将我的 UI 渲染成类似“Welcome Ken.”的内容。但是......如果我进入我的数据库并手动将名称更改为..“Nek”,然后点击刷新按钮,我期待一个“Welcome Nek”。但相反,它仍然是“肯”。我可以看到在我的服务器端从数据库中检索到了正确的数据,但是当我使用 Apollo devtools 查看我的缓存时,我可以看到它仍然是以前的数据并且尚未使用新获取的数据进行更新。
在我在数据库中手动更改名称后,我在底部包含了一个日志。我唯一改变的是“first_name”字段从“Ken”到“Nek”就是这样。
除了尝试使用 refetch()、refetchQueries、轮询...我还尝试执行另一个突变,只是为了查看它是否会在重新渲染后更新,但也没有运气。
经过一些调试,我发现我的数据只有在我重新启动节点服务器后才会更新,这让我想知道我是否在我的设置配置中做错了什么?因为在我的客户端,即使我清除了缓存并进行了硬刷新,或者关闭了我的标签/浏览器,它仍然会抓取我的旧数据。我也没有使用持久链接。
ApolloConfig.js
const cache = new InMemoryCache();
const stateLink = withClientState({ cache, resolvers, defaults, typeDefs });
const authLink = setContext((request, prevContext) => ({
headers: { authorization: localStorage.getItem('token') || '' }
}));
const httpLink = createHttpLink({
uri: `${gqlUrl}graphql`
});
const link = ApolloLink.from([stateLink, authLink.concat(httpLink)]);
const client = new ApolloClient({
link,
cache,
connectToDevTools: true
});
服务器端 index.js
app.use(
'/graphql',
bodyParser.json(),
graphqlAuthentication,
graphqlExpress({
schema,
context: { loaders: createLoaders() }
})
);
app.use('/graphiql', graphiqlExpress({ endpointURL: '/graphql' }));
DashboardContainer.js 这里的 refetch 函数只是用来测试我的 props 是否会更新(当函数被调用时,我确实可以在我的服务器端看到正确获取的数据/请求)
class DashboardContainer extends Component {
refetch = () => {
this.props.data.refetch();
this.props.setUser({ variables: { user: this.props.data.user } });
};
render() {
return (
<div style={{ display: 'flex', justifyContent: 'center' }}>
<Dashboard {...this.props} />
<button onClick={this.refetch}>Refresh</button>
</div>
);
}
}
DashboardContainer.propTypes = {};
const query = gql`
query QUERY_USER_EMAIL($email: String!) {
user(email: $email) {
id
email
bcomm_client_id
first_name
last_name
__typename
}
}
`;
export default compose(
graphql(QUERY_GET_USER_EMAIL),
graphql(query, {
options: props => ({
variables: { email: props.data.email },
fetchPolicy: 'network-only'
})
}),
graphql(MUTATION_UPDATE_USER, { name: 'setUser' })
)(DashboardContainer);
服务器端 Schema.js
type User {
id: ID!
email: String
last_login: String
first_name: String
last_name: String
roles: String
is_active: Boolean
bcomm_client_id: ID
bcomm_access_token: String
}
type Query {
user(email: String!): User!
}
客户端 Queries.js
export const QUERY_GET_USER_EMAIL = gql`
{
email @client
}
`;
服务器端日志
------- USER -------
TextRow {
id: 15,
last_login: null,
first_name: 'NEK',
last_name: 'WOW',
roles: 'Admin',
is_active: 1,
email: 'hi@hi.com',
bcomm_client_id: null,
bcomm_access_token: null }
------- Request (POST) -------
{ host: 'localhost:8081',
connection: 'keep-alive',
'content-length': '244',
pragma: 'no-cache',
'cache-control': 'no-cache',
accept: '*/*',
origin: 'https://localhost:3000',
authorization: '',
'user-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36',
'content-type': 'application/json',
'accept-encoding': 'gzip, deflate, br',
'accept-language': 'en-US,en;q=0.9,fr;q=0.8' }
{ operationName: 'QUERY_USER_EMAIL',
variables: { email: 'hi@hi.com' },
query: 'query QUERY_USER_EMAIL($email: String!) {\n user(email: $email) {\n id\n email\n bcomm_client_id\n first_name\n last_name\n __typename\n }\n}\n' }
client.Store console.log
ROOT_QUERY:
email: "hi@hi.com"
user: {type: "id", id: "User:15", generated: false}
user({"email":"hi@hi.com"}): {type: "id", id: "User:15", generated: false} __typename: "AuthDefaults"
__proto__: Object
User:15:
bcomm_client_id: null
email: "hi@hi.com"
first_name: "KEN"
id: "15"
last_name:"WOW"
【问题讨论】: