reactjs - 使用 Refetch 和 apollo 重新渲染查询和组件

标签 reactjs graphql apollo apollo-client

我在通过查询用新数据重新水合组件时遇到问题。为了设定前提,我有两个像这样的兄弟组件:

<Container>
 <Navbar />
 <Login /> || <Home />
</Container

基本上在我的登录组件中,当我点击登录时,我有一个像这样运行的突变:

this.props.mutate({
        variables: { token },
        refetchQueries: () =>  ['isAuthenticated']
    }).then((data) => {
      console.log(data);
      this.props.history.push(`/`);
    })

所以结果最终是没有任何重新渲染,我在导航组件中使用 console.log() 来查看它的 Prop 是否已更改,但它没有更改,但是在我的网络选项卡和缓存中是它应该返回的数据。

我的导航项组件如下所示:

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() 工作正常,但是我的 Prop 返回时带有陈旧的信息/错误或数据。

最佳答案

这可能无法回答您有关重新获取查询的问题,但在登录操作上使用 client.resetStore() 是一个很好的做法。因为您可能希望在用户登录后重新获取 Apollo Store 中缓存的所有结果。

这还应该解决依赖于查询数据的组件上的任何重新渲染问题。

组件只有在接收这些查询结果作为 props 时才会重新渲染。

关于reactjs - 使用 Refetch 和 apollo 重新渲染查询和组件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51110407/

相关文章:

reactjs - 开发本地主机上的 Next JS 13 应用程序目录快速刷新无法按预期工作

reactjs - 在 create-react-app 上运行构建后出现空白页面

reactjs - 如何使用@testing-library/react 测试 Ant 设计日期选择器?

javascript - 如何使用 GraphQL 查询返回目录中的文件列表?

node.js - createReadStream() 抛出 RangeError : Maximum call stack size exceeded when uploading file

meteor - Apollo/GraphQl-类型必须为输入类型

reactjs - Apollo useLazyQuery 钩子(Hook)在重新获取时使用旧变量(而不是新变量)

reactjs - 使用 apollo 和 graphql 上传大于 16 kb 的文件时会损坏

reactjs - 处理从express到react的错误响应

android - 如何在 Android 上使用 IAM 或 Cognito Pool 作为身份验证方法而不是 API key