[英]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.