繁体   English   中英

每次在react-apollo和graphql中调用组件时如何将查询重新发送到服务器

[英]How to resend queries to server every time a component is called in react-apollo and graphql

我有这个项目,有点像Facebook。 这个想法是,当用户在其个人资料页面中时,他们应该看到朋友的用户名列表。 单击每个用户名后,应用程序将从URL中获取该人的ID,然后将graphql查询发送到服务器,以获取该人的所有相关详细信息。 下面是当用户单击任何朋友的用户名时调用的方法。 这按预期工作:

onClickFriend(e) {
    e.preventDefault()
    this.props.history.push(`/friends/${ e.target.id}`)
}

然后,在处理用户访问的url的组件(即显示好友配置文件的组件)中包含以下代码:

import React from 'react'
import PostsColumn from "./posts/PostsColumn"
import NewPostForm from "./posts/NewPostForm"
import {fetchFriendProfile} from "../queries/queries"
import {graphql} from 'react-apollo'
import {withRouter } from 'react-router'

const FriendProfile=({data})=>{
    const {loading, error, fetchFriendProfile} = data
    if (loading) return <p>Loading...</p>
    if (error) return <p>{error}(</p>

    const {username, birthday, profile_picture} = fetchFriendProfile
    return (
        <div className="row">
            <div className="col-sm-3">
                <br/>

                <img src={`/uploads/${profile_picture}`} alt="Profile picture" width="200" height="200"/>
                <ul>
                    <li>{username}</li>
                    <li>{new Date(birthday).toDateString()}</li>
                </ul>
            </div>
            <div className="col-sm-6">
                <br/>
                <br/>
                <div className="content-feed">
                    <NewPostForm/>
                </div>

                {/*<PostsColumn />*/}
            </div>


        </div>
    )
}
export default graphql(fetchFriendProfile)(withRouter(FriendProfile))

而graphql查询是:

import {gql} from 'apollo-boost'
const fetchPalPosts = gql`
  {
 fetchFriendPosts(id:"${window.location.pathname.split('/')[2]}") {
    username
    birthday
    profile_picture
    }
    }
    `
export { fetchFriendProfile}

最初,当网站加载时,我会看到所有朋友的用户名列表,并且在第一次单击任何用户时,都会得到所有相关详细信息。 但是,当我返回并单击另一个用户时,此配置文件组件为我提供了我单击的第一个用户的配置文件详细信息。 url更改为反映此新单击的人员的id,但是该组件未显示正确的详细信息。 只有重新加载页面后,我才能获得正确的详细信息。 通过进行一些调试,我意识到从第二次开始,单击这些用户名中的任何一个,甚至都不会查询服务器。 只有当我重新加载页面时,才进行查询。 我需要帮助,以了解每次在react-apollo和graphql中调用组件时如何将查询重新发送到服务器。 (是graphql的初学者)

除了查询之外, graphql HOC graphql配置对象作为其第二个参数,使您可以微调查询的行为。 例如,您可以定义fetchPolicy来确定Apollo如何使用缓存。 默认情况下,在获取相同查询时,Apollo将首次访问服务器,然后将缓存用于后续调用(这称为cache-first )。 如果您希望组件在挂载时始终点击请求,则可以将提取策略设置为network-only

export default graphql(fetchFriendProfile, {
  options: (props) => ({
    fetchPolicy: 'network-only',
  }),
})(withRouter(FriendProfile))

您可以在此处阅读有关获取策略的更多信息。

也就是说,您无需更改获取策略即可实现所需的行为。 问题的一部分是您正在有效地对id输入进行硬编码-相反,您应该在每个查询中将任何动态输入作为变量传递。 这意味着您的查询需要看起来像这样:

# Note: the actual type for $id will have to match your schema!
query WhateverNameYouLike ($id: ID!){ 
  fetchFriendPosts(id: $id) {
    username
    birthday
    profile_picture
  }
}

然后,您可以像这样传递变量:

export default graphql(fetchFriendProfile, {
  options: (props) => ({
    variables: {
      id: window.location.pathname.split('/')[2],
    },
  }),
})(withRouter(FriendProfile))

旁注:看起来您也正在使用React Router,因此您应该能够从match.params获取ID,而不是自己解析位置。 在这里阅读更多。

最后,重要的是要认识到Apollo会规范化其缓存的数据-并且它依赖于数据的id (或_id )属性来实现。 因此,如果您希望cache-first行为按预期工作,则需要a)确保始终在查询中请求id字段,或者b)通过相应地配置InMemoryCache来告诉Apollo使用其他字段作为id 听起来您已经有一个id字段,所以修改查询以包含它就足够简单了:

query WhateverNameYouLike ($id: ID!){ 
  fetchFriendPosts(id: $id) {
    id
    username
    birthday
    profile_picture
  }
}

您可以在此处阅读有关缓存规范化以及如何使用dataIdFromObject自定义InMemoryCache的默认行为的更多信息

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM