我在通过查询为组件补充新数据时遇到问题。为了设置前提,我有两个像这样的兄弟姐妹:
<Container>
<Navbar />
<Login /> || <Home />
</Container
基本上,在我的登录组件中,我有一个突变,当我点击登录时,运行如下:
this.props.mutate({
variables: { token },
refetchQueries: () => ['isAuthenticated']
}).then((data) => {
console.log(data);
this.props.history.push(`/`);
})
所以结果最终是什么也没有回报,我在导航组件中使用console.log()来查看其属性是否已更改,但是没有改变,但是在我的网络标签和缓存中应该返回的数据。
我的导航项组件如下:
import React, { Component } from "react";
import { Link, withRouter } from "react-router-dom";
import gql from "graphql-tag";
import { graphql, compose } from "react-apollo";
import { withStyles } from "@material-ui/core/styles";
import List from "@material-ui/core/List";
import ListItem from "@material-ui/core/ListItem";
import Button from "@material-ui/core/Button";
import headerLinksStyle from "./HeaderLinksStyle";
import { LockOpen, GetApp, Info } from "@material-ui/icons";
const isLoggedInQuery = gql`
query isLoggedInQuery {
token @client
}
`;
const loggedInMutation = gql`
mutation authToken($token: String!) {
assignAuthToken(token: $token) @client {
token
}
}
`;
const userQuery = gql`
query isAuthenticated {
currentUser {
id
firstName
lastName
gender
location
password
email
permissions {
id
name
displayOrder
description
}
roles {
id
name
description
displayOrder
}
}
}
`;
class HeaderLinks extends Component {
logout = () => {
localStorage.removeItem("auth_token");
this.props.mutate({
variables: { token: null }
});
this.props.history.push(`/`);
};
refetch = () => {
console.log("refetch")
this.props.user.refetch();
}
render() {
const { classes } = this.props;
const { token } = this.props.data;
const isLoggedIn = token;
console.log(this.props);
return (
<List className={classes.list}>
{!isLoggedIn && (
<ListItem className={classes.listItem}>
<Link to="/login" style={{ color: "inherit" }}>
<Button color="inherit" className={classes.navLink}>
<LockOpen className={classes.icon} />Login
</Button>
</Link>
</ListItem>
)}
{!isLoggedIn && (
<ListItem className={classes.listItem}>
<Link to="/signup" style={{ color: "inherit" }}>
<Button color="inherit" className={classes.navLink}>
<GetApp className={classes.icon} />Sign up
</Button>
</Link>
</ListItem>
)}
<ListItem className={classes.listItem}>
<Button color="inherit" className={classes.navLink} onClick={() => { this.refetch();}}>
<Info className={classes.icon} />About
</Button>
</ListItem>
{isLoggedIn && (
<ListItem className={classes.listItem}>
<Button
color="inherit"
className={classes.navLink}
onClick={event => {
this.logout();
}}
>
<LockOpen className={classes.icon} />Logout
</Button>
</ListItem>
)}
</List>
);
}
}
export default compose(
graphql(isLoggedInQuery),
graphql(loggedInMutation),
graphql(userQuery, { name: "user", options: {fetchPolicy: 'network-only'}}),
withStyles(headerLinksStyle),
withRouter
)(HeaderLinks);
解散this.props.user.refetch()可以正常工作,但是我的道具又返回了过时的信息/错误或数据。
答案 0 :(得分:0)
这可能不会回答您有关重新获取查询的问题,但是在登录操作中使用client.resetStore()
是一个好习惯。由于您可能希望在用户登录后重新获取缓存在Apollo Store中的所有结果。
这还应该解决依赖于查询数据的组件上的任何重新渲染问题。
仅当组件将这些查询结果作为道具接收时,组件才会重新渲染。
答案 1 :(得分:0)
您是否正在使用graphiql工具?您应该对在currentUser
文件夹中导入的queries
进行查询。您还应该在Logout
文件夹中有一个mutations
突变,并导入它。这样,您可以在HeaderLinks
的末尾使用一个清洁的衬纸,如下所示:export default graphql(mutation)(graphql(query)(HeaderLinks));
并且仅用于初学者。我建议像这样重构:
import React, { Component } from 'react';
import { graphql } from 'react-apollo';
import { Link } from 'react-router';
import query from '../queries/CurrentUser';
import mutation from '../mutations/Logout';
class HeaderLinks extends Component {
onLogoutClick() {
this.props.mutate({});
}
renderButtons() {
const { loading, user } = this.props.data;
if (loading) {
return <div />;
}
if (user) {
return (
<li>
<a onClick={this.onLogoutClick.bind(this)}>Logout</a>
</li>
);
} else {
return (
<div>
<li>
<Link to="/signup">Signup</Link>
</li>
<li>
<Link to="/login">Login</Link>
</li>
</div>
);
}
}
render() {
return (
<nav>
<div className="nav-wrapper">
<Link to="/" className="brand-logo left">
Home
</Link>
<ul className="right">{this.renderButtons()}</ul>
</div>
</nav>
);
}
}
export default graphql(mutation)(graphql(query)(Header));
现在,上面假设要实现CSS样式化,您可能正在使用其他东西,这很好,只需反映一下即可,但是我认为我上面分享的内容更加简洁,可以帮助您。
因此,在运行突变后,我会说我希望GraphQL自动重新获取此查询列表,即使它只是一个查询,但是我要传递一个数组,因为那是帮助程序希望我这样做的原因:
class HeaderLinks extends Component {
onLogoutClick() {
this.props.mutate({
refetchQueries: [{}]
});
}
所以我只有一个查询要重新运行,它是我导入为查询的currentUser
查询,我将这样定义它:
class HeaderLinks extends Component {
onLogoutClick() {
this.props.mutate({
refetchQueries: [{ query: query }]
});
}
键值具有相同的变量名,因此我们可以将其压缩为这样的查询:
class HeaderLinks extends Component {
onLogoutClick() {
this.props.mutate({
refetchQueries: [{ query }]
});
}
因此,在运行变异后,请重新运行此查询并重新呈现与该查询关联的任何组件,并且标题应在屏幕上自动更新。