国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

21 分鐘學(xué) apollo-client 系列:獲取數(shù)據(jù)

robin / 3412人閱讀

摘要:分鐘學(xué)是一個系列,簡單暴力,包學(xué)包會。一旦組件掛載后,會自動進(jìn)行數(shù)據(jù)請求,前提是客戶端提供的和后端的相符。如果回調(diào)返回直接不作請求。在組件內(nèi)進(jìn)行分頁請求之前提到了,這個裝飾器為添加了對象,其中有個函數(shù)為。

21 分鐘學(xué) apollo-client 是一個系列,簡單暴力,包學(xué)包會。

搭建 Apollo client 端,集成 redux
使用 apollo-client 來獲取數(shù)據(jù)
修改本地的 apollo store 數(shù)據(jù)
提供定制方案

請求攔截

封裝修改 client 的 api

apollo store 存儲細(xì)節(jié)
寫入 store 的失敗原因分析和解決方案

使用 Apollo 獲取數(shù)據(jù)

推薦先看:GraphQL 入門: 連接到數(shù)據(jù)
本文只做補(bǔ)充。

下面編寫一個最簡單的 Container,觀察是否能 query 到數(shù)據(jù)。

container.jsx

import React, { PureComponent } from "react";
import { graphql } from "react-apollo";
import query from "./query.gql";

@graphql(query)
export default class ApolloContainer extends PureComponent {
    render() {
        console.log(this.props);
        return 
Hello Apollo
; } }

@graphql(query) 是 apollo 提供的高階組件,以裝飾器的形式包裹你的組件。這里是最簡單的情況,只傳一個 query。

query 語法

基本的 query 語法可以參看官方文檔 Queries and Mutations | GraphQL,這里提一下 Apollo 特有的一些語法。

query.gql

#import "../gql/pageInfo.gql"
#import "@/gql/topic/userTopicEntity.gql"

query topic($topicId: Int!, $pageNum: Int = 1) {
    community {
        topicEntity {
            listByTopicId(topicId: $topicId, pageSize: 10, pageNum: $pageNum) {
                pageInfo {
                    ...pageInfo
                }
                edges {
                    ...userTopicEntity
                }
            }
        }
    }
}

前兩行 import 了其它的 fragment。想必你已經(jīng)知道,GraphQL 主要通過 fragment 來組合分形 Query。一個好的實(shí)踐是盡量對業(yè)務(wù)實(shí)體編寫 fragment 以便復(fù)用。
代碼脫敏的關(guān)系我就不放詳細(xì)的 fragment 了。

上一節(jié)我們在 webpack 中配置了 graphql-tag/loader,這個 loader 允許你將 query 、fragment 這些 schema 字符串,以 .gql 文件的形式保存,在 import 時轉(zhuǎn)化成 js 代碼。

其余部分,基本上和 GraphQL 原生寫法是一樣的,注意幾個點(diǎn):

一次請求只能包含一個 query,而且不能包含未使用的 fragment。

#import 語法是 loader 提供的,語法和 js 的 import 差不多,除了不能解構(gòu) 。
如果你 webpack 配置了 alias 就能使用第二行那種寫法。注意,它會把該文件內(nèi)所有的內(nèi)容都 import 進(jìn)來,所以不能在一個 gql 文件里寫多個 queryfragment。

對了,為了最小化實(shí)踐,你可以先寫不帶參數(shù)的 query。也先不要寫 union type。

props.data 的數(shù)據(jù)結(jié)構(gòu)

這樣就好了嗎,是的。一旦組件掛載后,會自動進(jìn)行數(shù)據(jù)請求,前提是客戶端提供的 query schema 和后端的相符。

如果請求成功后,會發(fā)生什么事情呢?我們可以查看 this.props 打出的 log 來驗(yàn)證:

// this.props
{
    // ....
    data: {
        // ...
        community: { ... }, // 這是獲取到的數(shù)據(jù),結(jié)構(gòu)和你提供的 query schema 一致
        loading: false, // 請求過程中為 true
        networkStatus: 7, // 從 0-8,具體值的含義看這個文件 https://github.com/apollographql/apollo-client/blob/master/src/queries/networkStatus.ts
        variables: { ... }, // 請求時所用的參數(shù)
        fetchMore, // 一個函數(shù),用于在組件內(nèi)「繼續(xù)請求」,一般用于分頁請求
        refetch, // 函數(shù),用于組件內(nèi)「強(qiáng)制重新請求」
        updateQuery, // 請求成功后立即調(diào)用,用于更新本地 store
    }
}
高級請求

我們僅改寫裝飾器部分

@graphql(query, {
    skip: props => !isValid(props),
    options: props => ({
        variables: {
            topicId: getIdFromUrl(),
        },
    }),
})

其中

skipshouldComponentUpdate 的效果是一樣的,決定是否 re-fetch。如果回調(diào)返回 false 直接不作請求。

options 返回一個函數(shù),用以設(shè)置請求的細(xì)節(jié),比如 variables 用于設(shè)置 query 參數(shù)

更詳細(xì)的文檔可以查閱

API: graphql container with queries | Apollo React Docs

GraphQL 入門: Apollo Client - 連接到數(shù)據(jù)

分頁請求

如文檔 Pagination | Apollo React Docs 所說,Apollo 支持兩種分頁

offset-based

按條數(shù)偏移量來請求分頁,請求時提供兩個參數(shù)

limit:相當(dāng)于 pageSize,一頁最多取多少個

offset: 條數(shù)偏移量,第 n 頁的 offset = limit * n

可見你需要自己維護(hù)一個 pageNum: n 來實(shí)現(xiàn)按頁碼分頁

cursor-based

這是 Relay 風(fēng)格的請求,cursor 用于記錄下個請求開始時,返回的第一個元素的位置,一般可以用該元素的 id 來標(biāo)識。

RESTful 風(fēng)格

我們后端并沒有采取上面任何一種,而是提供了一個 pageInfo 對象,由前端傳入所需參數(shù),保持和 RESTful api 相似的風(fēng)格。

query.gql

#import "../gql/pageInfo.gql"
#import "@/gql/topic/userTopic.gql"

query topic($topicId: Int!, $pageNum: Int = 1) {
    community {
        topicEntity {
            listByTopicId(topicId: $topicId, pageSize: 10, pageNum: $pageNum) {
                pageInfo {
                    ...pageInfo
                }
                edges {
                    ...userTopicEntity
                }
            }
        }
    }
}

pageInfo.gql

fragment pageInfo on PageInfo {
    pageNum     # 頁碼
    pageSize    # 每頁條數(shù)
    pages       # 總頁數(shù)
    total       # 總條數(shù)
}

聲明下,由于我們只使用 GraphQL 的 Query 功能,所以沒研究過這種格式是否會影響 Mutation。現(xiàn)在或以后有 Mutation 需求的,盡量采用官方推薦的前兩種吧。

在組件內(nèi)進(jìn)行分頁請求

之前提到了, graphql 這個裝飾器為 this.props 添加了 data 對象,其中有個函數(shù)為 fetchMore。

fetchMore 看名字就知道是用來作分頁請求的。

下面我們看一個比較真實(shí)的例子,許多業(yè)務(wù)相關(guān)的代碼都用表示其作用的函數(shù)替代了,注意看注釋:

import React, { PureComponent } from "react";
import { graphql } from "react-apollo";
import { select } from "./utils";
// 注意,這里用的 query 是 「RESTful 風(fēng)格」那一節(jié)中貼出的 schema
import query from "./query.gql";

@graphql(query, {
    skip: props => !isValid(props),
    options: props => ({
        variables: {
            topicId: getIdFromUrl(),
        },
    }),
})
@select({
    // 你可以寫一個函數(shù),從 this.props.data 里過濾出當(dāng)前列表的 pageInfo,直接添加到 this.props.pageInfo
    pageInfo: getPathInfoFromProps(props),
})
export default class TopicListContainer extends PureComponent {
    hasMore = () => {
        const { pageNum = 0, pages = 0 } = this.props.pageInfo || {};
        return pageNum < pages;
    }

    loadNextPage = () => {
        const { pageInfo = {}, data } = this.props;
        const { pageNum = 1 } = pageInfo;
        const fetchMore = data && data.fetchMore;

        if (!this.hasMore()) return;
        if (!fetchMore) return;

        return fetchMore({
            variables: {
                // 是的,這里不需要把你在 `@graphql` 裝飾器中定義的其它 variables 再寫一遍
                // apollo 會自動 merge
                pageNum: pageNum + 1,
            },
            // 這個回調(diào)函數(shù),會在 fetch 成功后自動執(zhí)行,用于修改本地 apollo store
            updateQuery: (prev, { fetchMoreResult }) => {
                if (!fetchMoreResult) return prev;

                // 嘗試 log 下 `fetchMoreResult`,其返回的數(shù)據(jù)結(jié)構(gòu),和 query 中的 schmea 是一致的

                // parseNextData 返回新數(shù)據(jù)。
                // 新數(shù)據(jù)的數(shù)據(jù)結(jié)構(gòu)必須和 query schema 一樣
                // NOTE: 此處會有大坑,如果你發(fā)現(xiàn)最終數(shù)據(jù)并未改變,請閱讀后文
                return parseNextData(prev, fetchMoreResult);
            }
        });
    }

    render() {
        return (
            
        );
    }
}

updateQuery 中,使用 parseNextData 經(jīng)過一些處理,返回新數(shù)據(jù)給 apollo,apollo 將把它寫入到 apollo store 中。
注意,這里至少會有兩處大坑

如果寫入失敗,是會靜默失敗的,也就是說 沒有任何報錯提示

如果寫入數(shù)據(jù)的結(jié)構(gòu),和 query schema 不符,就會寫入失敗。

但寫入失敗的情況還不止于此!如果你發(fā)現(xiàn)最終數(shù)據(jù)并未改變,可能是中招了,解毒方案 請閱讀 寫入 store 的失敗原因分析和解決方案

這段代碼只演示了如何 被動 地去修改本地的 apollo store 數(shù)據(jù),要問如何 主動 去修改 apollo store,請看這篇文章: 修改本地的 apollo store 數(shù)據(jù)








文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/91924.html

相關(guān)文章

  • 21 分鐘學(xué) apollo-client 系列:擴(kuò)展 ApolloClient 的 api

    摘要:分鐘學(xué)是一個系列,簡單暴力,包學(xué)包會。那怎么辦呢本章就教你非常簡單地實(shí)現(xiàn)擴(kuò)展的。我們可以借鑒的的寫法,為的實(shí)例添加一些自己的方法。更重要的是,也會有的效果,上一個的輸出會成為下一個的輸入,便于組合。 21 分鐘學(xué) apollo-client 是一個系列,簡單暴力,包學(xué)包會。 搭建 Apollo client 端,集成 redux使用 apollo-client 來獲取數(shù)據(jù)修改本地的 ...

    levy9527 評論0 收藏0
  • 21 分鐘學(xué) apollo-client 系列:簡單搭建

    摘要:分鐘學(xué)是一個系列,簡單暴力,包學(xué)包會。其中提到了等需要后端配合的東西,徒增了配置的復(fù)雜性。如果不行,再跟隨我的簡單步驟試試。環(huán)境要求請確保你已經(jīng)搭建了自己的環(huán)境下文在行號前添加表示刪除的原代碼,表示新增的代碼。 21 分鐘學(xué) apollo-client 是一個系列,簡單暴力,包學(xué)包會。 搭建 Apollo client 端,集成 redux使用 apollo-client 來獲取數(shù)據(jù)...

    ranwu 評論0 收藏0
  • 21 分鐘學(xué) apollo-client 系列:寫入失敗的原因和解決方案

    摘要:分鐘學(xué)是一個系列,簡單暴力,包學(xué)包會。一旦你丟失了,可能會導(dǎo)致寫入失敗,或者盡管寫入了,但本該攜帶的那一層的數(shù)據(jù)沒有寫入。 21 分鐘學(xué) apollo-client 是一個系列,簡單暴力,包學(xué)包會。 搭建 Apollo client 端,集成 redux使用 apollo-client 來獲取數(shù)據(jù)修改本地的 apollo store 數(shù)據(jù)提供定制方案 請求攔截 封裝修改 clie...

    Baoyuan 評論0 收藏0
  • 21 分鐘學(xué) apollo-client 系列:apollo store 存儲細(xì)節(jié)

    摘要:分鐘學(xué)是一個系列,簡單暴力,包學(xué)包會。內(nèi)部通過自己的私有沒有暴露給開發(fā)者來更新這個。相當(dāng)于這個就是自己維護(hù)的,它將所有通過得到的數(shù)據(jù)保存在這里。的生成規(guī)則根據(jù)官方文檔的說法,在創(chuàng)建時,可選設(shè)置。如果不存在,則可能出現(xiàn)。 21 分鐘學(xué) apollo-client 是一個系列,簡單暴力,包學(xué)包會。 搭建 Apollo client 端,集成 redux使用 apollo-client 來...

    lavor 評論0 收藏0
  • 21 分鐘學(xué) apollo-client 系列:請求攔截和 FragmentMatcher

    摘要:分鐘學(xué)是一個系列,簡單暴力,包學(xué)包會。接管了請求和狀態(tài)管理。一般在生產(chǎn)環(huán)境中,我們通常還希望做權(quán)限驗(yàn)證請求攔截等事務(wù)處理。 21 分鐘學(xué) apollo-client 是一個系列,簡單暴力,包學(xué)包會。 搭建 Apollo client 端,集成 redux使用 apollo-client 來獲取數(shù)據(jù)修改本地的 apollo store 數(shù)據(jù)提供定制方案 請求攔截 封裝修改 clie...

    Eastboat 評論0 收藏0

發(fā)表評論

0條評論

閱讀需要支付1元查看
<