react-apollo 選中以及數(shù)據(jù)無法刷新

記錄一下這陣子寫react時(shí) Apollo踩下的坑

背景: 項(xiàng)目使用 creat-react-app 搭建腳手架, 技術(shù)棧GraphQL+Apollo+React 爽蝴,所以下面這幾個(gè)包少不了

  • apollo-boost: Package containing everything you need to set up Apollo Client
  • react-apollo: View layer integration for React
  • graphql-tag: Necessary for parsing your GraphQL queries
  • graphql: Also parses your GraphQL queries

說明白了 GraphQL 和數(shù)據(jù)庫本身并沒有直接關(guān)系鸯隅,但相當(dāng)于平時(shí)寫的 Get Post請求
這里主要用 react-apollo 的兩個(gè)核心組件: Query Mutation

Query

Apollo 的<Query></Query> 查詢組件只能在render() 里面執(zhí)行巨朦,而在react中 render() 顧名思義--渲染 是不能修改組件的state 也就是說 setState是用不了了,那么我有個(gè)問題 如果獲取數(shù)據(jù)之后赶撰,傳入子組件那么

1. 子組件的操作 如何修改狀態(tài)?
2. 子組件修改狀態(tài)之后舌镶,父組件如何刷新數(shù)據(jù)?


const IMAGE_ORDER_LIST = gql`
  query OrderListQuery($status:Int, $page: Int, $priceSort: String, $keyword: String, $time: String) {
    OrderListQuery(status: $status, page: $page ,priceSort: $priceSort, keyword: $keyword, time: $time) {
      items {
        order_num
        id
        price
        image_url
        status_msg
        created_on
      }
      paginate {
        current_page
        last_page
      }
    }
}`

class Parent extends React.Component {
  render() {
    <Query query={IMAGE_ORDER_LIST}>
      {({ loading, error, data }) => {
        if (loading) return //do something
        if (error) return //do something
        return (
          <div>
            <ChildA orders={data.xx} ></ChildA>
            <ChildB orders={data.aa} ></ChildB>
            <ChildC orders={data.ss} ></ChildC>
          </div>
        )
      }}
    </Query>
  }
}

折騰了好久,最后找到暫時(shí)解決的辦法豪娜,記錄下

問題1

問題大致還原成: 實(shí)現(xiàn) 單選 or 全選訂單餐胀,并且進(jìn)行 駁回 or 通過操作 傳送門 ->

想過的點(diǎn)

  1. 想過父組件傳遞函數(shù)給checkbox組件里面更改自身狀態(tài),但是更改后的狀態(tài)如何傳遞給爺爺組件.. 這就尷尬了
  2. 在爺瘤载、 父 否灾、子組件中,將操作邏輯放置 父組件鸣奔,但是三個(gè)組件的通訊問題 又成了問題墨技,不會要用redux吧...

后來找到例子: https://codesandbox.io/s/j4krmvw4ky 實(shí)際上是用 狀態(tài)提升方法 由此想到思路, 把 Parent 組件中的 ChildA 挎狸、 ChildB 扣汪、 ChildC 重新封裝起來成 BigChild組件,然后將Parnet 獲取到的數(shù)據(jù)傳入 BigChild轉(zhuǎn)化為state锨匆,這樣就可以更改狀態(tài)啦~


//Parent .js
class Parent extends React.Component {
  render() {
    <Query query={IMAGE_ORDER_LIST}>
      {({ loading, error, data }) => {
        if (loading) return //do something
        if (error) return //do something
        return (
          <div>
            <BigChild orders={data} ></BigChild>
          </div>
        )
      }}
    </Query>
  }
}

//BigChild .js
class BigChild extends React.Component {
  constructor(props) {
    super(props)
    this.state = {
      data: this.props.orders
    }
  }

  render() {
    let { data } = this.state
    return (
      <div>
        <ChildA orders={data} ></ChildA>
        <ChildA orders={data} ></ChildA>
        <ChildA orders={data} ></ChildA>
      </div>
    )
  }
}

問題2

問題1解決了崭别,訂單操作完成之后,重新進(jìn)入Parent 頁面之后 render() 還是修改之前的數(shù)據(jù)

查了文檔,發(fā)現(xiàn)apollo是有緩存機(jī)制的

By default your component will try to read from the cache first, and if the full data for your query is in the cache then Apollo simply returns the data from the cache 【Click to read me!】

而apollo自帶兩種刷新數(shù)據(jù)方法是 pollInterval 以及 refetch

pollInterval

顧名思義 輪詢紊遵,類似setInterVal()账千, 周期可以作為參數(shù) 自定義,使用方法是 pollInterval ={ time }

  //500毫秒查詢一次


<Query
  query={IMAGE_ORDER_LIST}
  pollInterval={500}
  notifyOnNetworkStatusChange  //一定要開啟暗膜,監(jiān)控狀態(tài)碼
>
  {({ loading, error, data, startPolling, stopPolling }) => {
    //loading  error就似乎沒用了

    if (networkStatus === 7) {
      stopPolling()  //停止輪詢

      //加載完成

    } else if (networkStatus < 7) {

      return //loading

    } else if (networkStatus === 8) {

      return //出錯(cuò)

    }
  }}
</Query>

狀態(tài)碼:

  1. loading: 該查詢從未運(yùn)行過匀奏,現(xiàn)在請求正在等待
  2. setVariables:查詢的變量發(fā)生變化
  3. fetchMore: 表示fetchMore在此查詢上調(diào)用了該命令,并且創(chuàng)建的網(wǎng)絡(luò)請求當(dāng)前正在運(yùn)行
  4. refetch: 這意味著refetch已在查詢中調(diào)用并且重新獲取請求當(dāng)前正在運(yùn)行学搜。
  5. ...略
  6. poll: 表示輪詢查詢當(dāng)前正在運(yùn)行
  7. ready: 加載完成
  8. error: 錯(cuò)誤

refetch

這個(gè)非常實(shí)用娃善,如果在組件內(nèi)更新,或者點(diǎn)擊事件之類 更新數(shù)據(jù)瑞佩,直接參考說明文檔例子,點(diǎn)擊即可實(shí)現(xiàn)聚磺。

const DogPhoto = ({ breed }) => (
  <Query
    query={GET_DOG_PHOTO}
    variables={{ breed }}
    skip={!breed}
  >
    {({ loading, error, data, refetch }) => {
      if (loading) return null;
      if (error) return `Error!: ${error}`;

      return (
        <div>
          <img
            src={data.dog.displayImage}
            style={{ height: 100, width: 100 }}
          />
          <button onClick={() => refetch()}>Refetch!</button>
        </div>
      );
    }}
  </Query>
);

看上去非常實(shí)用,但是我的這個(gè)問題: 當(dāng)訂單操作完成 重新進(jìn)入parent組件頁面炬丸,再立即執(zhí)行refetch() 似乎不太可能瘫寝,如果直接添加 refetch()

{({ loading, error, data, refetch }) => {
  refetch()
  render (
    //return something
  ) 
}}

會發(fā)現(xiàn) 頁面一直在refetch 使用了stopPolling 也不會停止, 后來使用 訂單操作完成返回一個(gè)參數(shù)給 parent頁面稠炬,parent頁面根據(jù)參數(shù)判斷 是否進(jìn)行refetch 同樣也不行焕阿!
另外想到 添加一個(gè)隱藏button 讓頁面進(jìn)入的時(shí)候自執(zhí)行,結(jié)果頁面抽搐了...
所以只能放棄 refetch() 這個(gè)好看但用不著的方法... 難受

最后

pollInterval 根據(jù)狀態(tài)做了一些改善

//500毫秒查詢一次
render() {
  let loadNum = 0
  return (
    <Query
      query={IMAGE_ORDER_LIST}
      pollInterval={100}
      notifyOnNetworkStatusChange  //一定要開啟首启,監(jiān)控狀態(tài)碼
    >
      {({ loading, error, data, startPolling, stopPolling }) => {
        loadNum++   //輪詢時(shí)候增加
        if (networkStatus === 7 && loadNum > 3) {

          stopPolling()  //停止輪詢
          //加載完成  do something

        } else if (networkStatus <= 7) {
          return //loading
        } else if (networkStatus === 8) {
          return //出錯(cuò)
        }
      }}
    </Query>

  )
}

大功告成暮屡,還有其他的解決方法 還望大神指導(dǎo)!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末毅桃,一起剝皮案震驚了整個(gè)濱河市褒纲,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌钥飞,老刑警劉巖莺掠,帶你破解...
    沈念sama閱讀 217,509評論 6 504
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異代承,居然都是意外死亡汁蝶,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,806評論 3 394
  • 文/潘曉璐 我一進(jìn)店門论悴,熙熙樓的掌柜王于貴愁眉苦臉地迎上來掖棉,“玉大人,你說我怎么就攤上這事膀估♂:ィ” “怎么了?”我有些...
    開封第一講書人閱讀 163,875評論 0 354
  • 文/不壞的土叔 我叫張陵察纯,是天一觀的道長帕棉。 經(jīng)常有香客問我针肥,道長,這世上最難降的妖魔是什么香伴? 我笑而不...
    開封第一講書人閱讀 58,441評論 1 293
  • 正文 為了忘掉前任慰枕,我火速辦了婚禮,結(jié)果婚禮上即纲,老公的妹妹穿的比我還像新娘具帮。我一直安慰自己,他們只是感情好低斋,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,488評論 6 392
  • 文/花漫 我一把揭開白布蜂厅。 她就那樣靜靜地躺著,像睡著了一般膊畴。 火紅的嫁衣襯著肌膚如雪掘猿。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,365評論 1 302
  • 那天唇跨,我揣著相機(jī)與錄音稠通,去河邊找鬼。 笑死轻绞,一個(gè)胖子當(dāng)著我的面吹牛采记,可吹牛的內(nèi)容都是我干的佣耐。 我是一名探鬼主播政勃,決...
    沈念sama閱讀 40,190評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼兼砖!你這毒婦竟也來了奸远?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,062評論 0 276
  • 序言:老撾萬榮一對情侶失蹤讽挟,失蹤者是張志新(化名)和其女友劉穎懒叛,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體耽梅,經(jīng)...
    沈念sama閱讀 45,500評論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡薛窥,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,706評論 3 335
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了眼姐。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片诅迷。...
    茶點(diǎn)故事閱讀 39,834評論 1 347
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖众旗,靈堂內(nèi)的尸體忽然破棺而出罢杉,到底是詐尸還是另有隱情,我是刑警寧澤贡歧,帶...
    沈念sama閱讀 35,559評論 5 345
  • 正文 年R本政府宣布滩租,位于F島的核電站赋秀,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏律想。R本人自食惡果不足惜猎莲,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,167評論 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望技即。 院中可真熱鬧益眉,春花似錦、人聲如沸姥份。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,779評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽澈歉。三九已至展鸡,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間埃难,已是汗流浹背莹弊。 一陣腳步聲響...
    開封第一講書人閱讀 32,912評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留涡尘,地道東北人忍弛。 一個(gè)月前我還...
    沈念sama閱讀 47,958評論 2 370
  • 正文 我出身青樓,卻偏偏與公主長得像考抄,于是被迫代替她去往敵國和親细疚。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,779評論 2 354

推薦閱讀更多精彩內(nèi)容