2017-08-02 46 views
4

在Apollo應用程序(也包括GraphQL/Relay)中,可以選擇將數據需求集中到組件中,或者最終自己組裝大型GraphQL查詢。我們選擇將數據需求集中到組件上,因爲我們期望更長的可維護性,因爲您不需要查看整個組件樹或頁面以查看所有數據需求,並且可以在本地添加新的需求。Apollo客戶端的片段組成:約定和樣板文件

我想知道如何使用Apollo客戶端來組合GraphQL片段。我知道該怎麼做,但我想知道我該如何做得更好。

目前,組成我的片段涉及了大量的樣板,特別是當我的組件剛剛傳遞的屬性未觸及。

片段聲明約定?

首先,讓我們來看一個簡單的組件:

export const User = ({ 
    user: { 
    firstName, 
    lastName, 
    job, 
    email, 
    pictureUrl, 
    color 
    }, 
    ...props 
}) => (
    <UserWrapper {...props}> 
    <UserAvatarWrapper> 
     <Avatar 
     firstName={firstName} 
     lastName={lastName} 
     color={color} 
     src={pictureUrl} 
     /> 
    </UserAvatarWrapper> 
    <UserContentWrapper> 
     {(firstName || lastName) && 
     <UserName> 
      {firstName} 
      {" "} 
      {lastName} 
      {" "} 
      {email && <UserEmailInline>{email}</UserEmailInline>} 
     </UserName>} 
     {job && <UserJob>{job}</UserJob>} 
    </UserContentWrapper> 
    </UserWrapper> 
); 
User.fragments = { 
    user: gql` 
     fragment User on User { 
      id 
      firstName 
      lastName 
      pictureUrl: avatar 
      job 
      color 
      email 
     } 
    `, 
}; 

這裏要作出一些選擇。似乎在大多數例子中都使用了某種約定,但是這個約定在文檔中並不明確。

  • 關鍵用於User.fragments。將它命名爲完全像組件的propName user是否有意義?

  • 片段的名稱:按照慣例,人們將其命名爲組件名稱,如果有用,則將其後綴爲片段所在的GraphQL類型。 (這裏UserUser可能會過度後綴)。

我認爲在同一個應用程序中遵循相同的約定是很好的,這樣所有的片段聲明都是一致的。那麼,有更多經驗的人能幫助我澄清這個似乎在許多阿波羅例子中使用的慣例嗎?

還原片段組成樣板?

讓我們按照我們設定的約定現在考慮一個Relationship組件。

const Relationship = ({ user1, user2 }) => (
    <RelationshipContainer> 
     <RelationshipUserContainer> 
     <User user={user1} /> 
     </RelationshipUserContainer/> 
     <RelationshipUserContainer> 
     <User user={user2} /> 
     </RelationshipUserContainer/> 
    </RelationshipContainer> 
); 
Relationship.fragments = { 
    user1: gql` 
     fragment RelationshipUser1User on User { 
      ...User 
     } 
     ${User.fragments.user} 
    `, 
    user2: gql` 
     fragment RelationshipUser2User on User { 
      ...User 
     } 
     ${User.fragments.user} 
    `, 
}; 

請注意,在這裏我聲明瞭2個看起來相同的片段。我認爲這是必要的,因爲有2個道具,你不應該假定道具上的數據要求是相同的。我們可以很容易想象一個具有me道具和friend道具的組件,您將在道具中獲得更多有關me道具的數據。

這工作正常,但它相當多的樣板和中間片段,看起來相當不必要。此外,它並不總是方便的,因爲從組件用戶的角度來看,您必須知道2個片段名稱才能使用它。

我試着用以下

Relationship.fragments = { 
    user1: User.fragments.user, 
    user2: User.fragments.user, 
}; 

這可以工作,以簡化這一點,但如果你這樣做,那麼片段名稱不再RelationshipUserXUser,但User相反,這意味着它打破了封裝,並不知怎的,你需要知道,在內部,Relationship組件正在使用User組件。

如果有一天,Relationship組件切換到使用替代表示,如UserAlt,這將需要使用關係片段重構所有組件,這是我想避免的。我認爲在這種情況下,修改只能發生在Relationship組件中。

結論

我想知道的最佳實踐與阿波羅組成的片段,讓組件保持真正的封裝,最好不涉及太多的樣板。

我已經做對了嗎?

如果我真的想撰寫查詢,這一切都是難以避免的嗎?

回答

3

如何做這樣的:

const userFragment = gql` 
    fragment Relationship_user on User { 
    ...User_user 
    } 
    ${User.fragments.user} 
`; 
Relationship.fragments = { 
    user1: userFragment, 
    user2: userFragment, 
}; 

除此之外,我建議你範圍的分片名稱如上圖所示,爲某種名字空間是必需的,否則它更可能你會碰到兩次使用相同的片段名稱。

  • User.fragments.user =>User_user
  • Relationship.fragments.user =>Relationship_user
+0

謝謝,我會盡力按照這些建議和報告,在這裏,如果它提高了代碼庫 –

+0

我開始使用這個慣例似乎是有道理的。順便說一句,這似乎也是本文中使用的慣例:https://medium.com/@wonderboymusic/upgrading-to-relay-modern-or-apollo-ffa58d3a5d59 –

相關問題