2017-08-31 63 views
3

我正在通過graphql構建一個身份驗證機制,並試圖找出爲什麼一個graphql連接組件在重新登錄後不會重新渲染...例如:Apollo graphql-connected React組件不重新渲染

  • /users我有請求的用戶的列表的反應-阿波羅graphql連接用戶組件。
  • 如果未提供令牌,服務器將返回認證錯誤;該組件呈現至/login路線;登錄成功後,Login組件將存儲該令牌並重新導回。
  • 用戶組件包裝器啓動graphql請求並在此期間呈現「正在加載...」。當graphql請求成功時,它會重新呈現並且用戶出現,yay。
  • 如果您從該頁面註銷,則/logout的註銷組件會丟棄該令牌,然後重新導回;用戶組件的請求再次獲取認證錯誤並將您發送到'/ login'。
  • 再次成功登錄後,您將被髮送回'/ users';它再次啓動一個到服務器的graphql請求(並呈現「加載...」),但是這次,當請求成功時,組件不會再次更新。

我可以看到graphql請求成功(在Chrome的調試已經眼看着APOLLO_QUERY_RESULT動作由反應 - 阿波羅的減速處理,並在店裏更新狀態)。

我試着找到React在檢查組件的道具是否已經改變,但我已經足夠了React調試noob,我還沒有想出在哪裏可以在Web檢查器中找到該代碼:也許我不明白React如何打包發佈。

我在登錄和註銷時都清除了ApolloClient的商店(通過調用resetStore()),因爲我不想意外重複使用來自其他身份驗證的數據;但是,刪除這些調用並不能解決問題。有趣的是(?),如果我通過在graphql()調用中提供{ options: { fetchPolicy: 'network-only' } }來強制連接繞過緩存,問題就會消失。 (不是一個可行的解決方案 - 我想從緩存中普遍受益。)

我已經建立了一個精簡的例子:https://github.com/bryanstearns/apollo-auth-experiment ,你可以看到它在CodeSandbox:https://codesandbox.io/s/m4nlpp86j(你可能會想從https://m4nlpp86j.codesandbox.io/的獨立瀏覽器窗口訪問正在運行的示例,因爲沙盒編輯器有點讓Web調試擴展很奇怪)。

回答

2

要修復此問題,請修改graphql HOC以在選項中包含notifyOnNetworkStatusChange

export const Users = graphql(usersQuery, { options: { notifyOnNetworkStatusChange: true } })(RawUsers); 

我不認爲你應該做到這一點 - 我認爲data.loading應該準確反映您的查詢的狀態,無論該選項被設置爲true,不像data.networkStatuslooks like it's a known bug

只要resetStore - 它實際上並沒有擦掉你的整個商店,而是將你的商店擦掉重新提交所有活動查詢。如果你想吹掉你的店鋪,因爲你已經將Redux和Apollo整合在一起,最簡單的做法是create an action to do that

您可能還想考慮基於會話的身份驗證機制,而不是依賴客戶端來持久保存令牌。實現服務器端非常簡單,不僅需要在客戶端進行更少的工作(不必在每次請求時都要記住傳遞令牌),並且可以讓用戶在離開後保持登錄狀態從頁面。

+0

非常好,Daniel,謝謝 - 這解決了我的問題,並且閱讀了您鏈接到的問題的歷史......教育:-)。我可能會切換到cookie認證;這也是我第一次使用localStorage進行的實驗。令牌具有跨多個域的優勢(儘管這還不是問題),Apollo可以輕鬆地爲所有請求進行全局配置:https://github.com/bryanstearns/apollo-auth-experiment/blob /ac05f47ace4fe00f346cbacde8d342306b6b94e0/src/index.js#L31 –

相關問題