天天看點

React 入門學習(九)-- 消息訂閱釋出

React 入門學習(九)-- 消息訂閱釋出
React 入門學習(九)-- 消息訂閱釋出

大家好,我是小丞同學,一名大二的前端愛好者

這篇文章是學習 React 中 GitHub 搜尋案例的學習筆記

非常感謝你的閱讀,不對的地方歡迎指正

願你忠于自己,熱愛生活

引言

在昨天寫的 Github 案例中,我們采用的是 axios 發送請求來擷取資料,同時我們需要将資料從 Search 中傳入給 App,再由 App 元件再将資料傳遞給 List 元件,這個過程會顯得多此一舉。同時我們要将 state 狀态存放在 App 元件當中,但是這些 state 狀态都是在 List 元件中使用的,在 Search 元件中做的,隻是更新這些資料,那這樣也會顯得很沒有必要,我們完全可以将 state 狀态存放在 List 元件中,但是這樣我們又會遇到技術難題,兄弟元件間的資料通信。那這裡我們就學習一下如何利用消息訂閱釋出來解決兄弟元件間的通信

消息釋出訂閱

要解決上面的問題,我們可以借助釋出訂閱的機制,我們可以将 App 檔案中的所有狀态和方法全部去除,因為本來就不是在 App 元件中直接使用這些方法的,App 元件隻是一個中間媒介而已

我們先簡單的說一下消息訂閱和釋出的機制

就拿我們平常訂雜志來說,我們和出版社說我們要訂一年的足球周刊,那每次有新的足球周刊,它都會寄來給你。

換到代碼層面上,我們訂閱了一個消息假設為 A,當另一個人釋出了 A 消息時,因為我們訂閱了消息 A ,那麼我們就可以拿到 A 消息,并擷取資料

那我們要怎麼實作呢?

首先引入 pubsub-js

我們需要先安裝這個庫

yarn add pubsub-js      

引入這個庫

import PubSub from 'pubsub-js'      

訂閱消息

我們通過 subscribe 來訂閱消息,它接收兩個參數,第一個參數是消息的名稱,第二個是消息成功的回調,回調中也接受兩個參數,一個是消息名稱,一個是傳回的資料

PubSub.subscribe('search',(msg,data)=>{
  console.log(msg,data);
})      
React 入門學習(九)-- 消息訂閱釋出

釋出消息

我們采用 publish 來釋出消息,用法如下

PubSub.publish('search',{name:'tom',age:18})      

有了這些基礎,我們可以完善我們昨天寫的 GitHub 案例

将資料的更新通過 publish 來傳遞,例如在發送請求之前,我們需要出現 loading 字樣

// 之前的寫法
this.props.updateAppState({ isFirst: false, isLoading: true })
// 改為釋出訂閱方式
PubSub.publish('search',{ isFirst: false, isLoading: true })      

這樣我們就能成功的在請求之前發送消息,我們隻需要在 List 元件中訂閱一下這個消息即可,并将傳回的資料用于更新狀态即可

PubSub.subscribe('search',(msg,stateObj)=>{
  this.setState(stateObj)
}      

同時上面的代碼會傳回一個 token ,這個就類似于定時器的編号的存在,我們可以通過這個 token 值,來取消對應的訂閱

通過 unsubscribe 來取消指定的訂閱

PubSub.unsubscribe(this.token)      

擴充 – Fetch

首先 fetch 也是一種發送請求的方式,它是在 xhr 之外的一種,我們平常用的 Jquery 和 axios 都是封裝了 xhr 的第三方庫,而 fetch 是官方自帶的庫,同時它也采用的是 Promise 的方式,大大簡化了寫法

如何使用呢?

fetch('http://xxx')
  .then(response => response.json())
  .then(json => console.log(json))
  .catch(err => console.log('Request Failed', err));       

它的使用方法和 axios 非常的類似,都是傳回 Promise 對象,但是不同的是, fetch 關注分離,它在第一次請求時,不會直接傳回資料,會先傳回聯系伺服器的狀态,在第二步中才能夠擷取到資料

我們需要在第一次 then 中傳回 response.json() 因為這個是包含資料的 promise 對象,再調用一次 then 方法即可實作

但是這麼多次的調用 then 并不是我們所期望的,相信看過之前生成器的文章的夥伴,已經有了想法。

我們可以利用 async 和 await 配合使用,來簡化代碼

可以将 await 了解成一個自動執行的 then 方法,這樣清晰多了

async function getJSON() {
  let url = 'https://xxx';
  try {
    let response = await fetch(url);
    return await reasponse.json();
  } catch (error) {
    console.log('Request Failed', error);
  }
}      

繼續閱讀