? ? ? ? 今天的內容是這個案例的實現,以及其中涉及到的內容,需要全部掌握,比如ref,受控組件,props在組件之中的傳遞,以及Pubsub包的使用這些前端React框架有關的內容。現在進入正題
1.github搜索案例(axios)
? ? ?
? ????????我們直接導入靜態頁面,這個方面html,css引入到組件拆分,我們就不說了,直接跳過。我們分為3個組件,首先App組件,Search組件以及List展示組件。
? ? ? ? ?現在我們分好了組件也引入了靜態html以及css之后頁面是這個效果
? ? ? ? ? ? ?圖片我們暫時隨便的用一種,現在我們首先要做的就是,我們要在Search組件中,實現一個效果,就是我們在點擊Search按鈕的時候,我們能夠去發送一個請求給服務器對應的端口上的服務,然后服務給我們一些我們搜索相關的數據返回,然后我們把這些數據想辦法給List組件,然后讓List組件展示出我們搜索出來的內容。
????????
? ? ? ? 首先添加一個點擊事件,當按鈕被點擊的時候,我們觸發函數,那么在這個函數中,我們發送請求之前需要獲取input輸入框的value值,因為我們搜索的關鍵字是我們自己輸入的,但是現在我們發生事件的元素并不是我們需要獲取value的元素,這時候我們就有兩種辦法,在按鈕元素點擊事件的時候拿到別的元素的value。
? ? ? ? 1.ref
? ? ? ? 我們直接給input設定ref ={event=>{this.keyWord = event}}相當于在ref中搞了一個箭頭函數,函數定義了我們Search類組件的一個新的實例對象值是當前元素input,這樣我們就可以在點擊事件發生的時候通過this.target.value拿到我們的內容,然后發送請求的時候作為參數傳給服務器。
????????
? ? ? 2.受控組件
? ? ? ? 受控組件就是當我們用jsx去寫一個標簽元素的時候,我們可以在state中設置一個value值為空,然后給input添加onChange監聽事件比如onChange={this.getValue},當監聽到變化的時候,函數執行,更新this.setState({value:event.target.value}) 就也可以獲取到value值。然后我們點擊事件中直接用this.state.value可以直接使用value作為參數傳給服務器了。
????????
? ? ?這是簡單一個示例,可以幫助我們去理解。
? ? ? ?那么我們Search組件就可以進行下一步了。發送請求獲得返回數據。我們這里使用的axios第三方庫。我們npm add axios安裝庫之后引入就可以axios方法了。
????????????????
? ? ? ? 這里發送請求無非三個關鍵點,要有發送的地址,
????????????????
? ? ? ? 還要有method params。不過我現在只是學習前端內容,這些并未涉及到,所以我只是知道有這個東西。這里我們希望是獲取與我們輸入內容相關的用戶名信息,所以是get請求。
????????
? ? ? ? 在這段代碼中,我們用axios.get方法向https://api.hithub.com/search.users發送請求,參數是我們的value。
????????
? ? ? ? 這是一個實例promise對象,我們在這后面用.then方法,里面的內容是如果請求發送成功,就輸出response.data 也就是返回來的數據,報錯就報錯
????????
? ? ? ? 這里我們控制臺可以看到輸出了內容,也就是我們響應體,也就是服務傳給我們的數據內容。我們要展示的就是items這個數組,也就是我們要的用戶信息。
? ? ? ? 這里我們是直接請求到github這個地址上的服務,為什么沒有跨域呢,因為github配置了cors,雖然不知道是什么,但是有了cors大家都可以在自己的服務器上直接訪問到github然后拿回數據,但是我們這樣頻繁的訪問會出錯,這時候我們就希望自己有一個代理服務器,上面有2個服務,也就是說,如果github因為頻繁訪問出錯,我們就用服務2,里面存放固定的數據給我們,這樣能保證我們只要通過代理服務器發送了請求,肯定是有數據回來的。
? ? ? ? 我們打開代理服務器
????????
? ? ? ? 我們現在只學的前端,服務器相關的只是知道是什么就行,不用知道原理。
? ? ? ? 但是這個服務器打開了我們就會有跨域的問題了,我們setupProxy.js配置代理服務器,我上一章以及提到過了,還有一個問題是我的電腦5000端口用不了,我這個電腦5000端口一直被占用,所以我這邊服務改為3002端口。
????????代理服務器搞定之后,我們直接訪問代理服務器就可以返回數據了。
????????
? ? ? ? 我們需要的數據是items,然后我們現在輸出的是response.data,那么response.data.items就是我們要用到的items。
? ? ? ? 現在我們拿到了數據,我們只需要傳給List組件就可以了。這些邏輯就是實現的邏輯,和TodoList是一樣的。調用函數Search組件傳返回的response.data.items用戶信息給App組件,更新state,然后傳給list遍歷展示。
????????剩下的功能是,發送請求的時候,希望搜索顯示loading以及展示區域有一個歡迎的效果。
????????
? ? ? ? 那么我們首先loading,以及歡迎,還有展示的內容items,以及err。我們需要四個動態效果,也就對應四個數據動態變化驅動頁面交互。我們現在先用props來傳遞,老公式,父組件App組件里面放state存四個數據。
????????
? ? ? ? 然后通過函數傳給Search組件,這里我們要注意的是,當發送請求前,我們的頁面是第一次打開,所以默認歡迎,當點擊事件發生的時候,這時候我們就isFirst改為false,isLoading改為true,然后當發送請求后,當有數據返回也就是請求成功了,我們改isLoading為false,然后傳users我們的items用戶信息。
? ? ? ? 剩下的就是App組件通過獲取的對象直接合并更新state。然后傳給List,List遍歷items渲染出來用戶信息到頁面上,這樣我們的搜索案例(axios)就完成了。
2.github搜索案例(Pubsub)
? ? ? ? 那么在標題一的下面我們是通過props來傳遞數據的,這樣在實際開發中有點不太適合,我們現在有一種新的方式,引入Pubsub訂閱發布庫,用里面的方法來直接實現Search組件和List組件之間的數據傳遞。
????????
? ? ? ? 這里是使用的方法,原理就像
???????????????????????
? ? ? ? 用語言描述就是?A組件 想要 B組件的數據,那么A組件就要訂閱一個 消息,然后定義消息名,B組件發布消息,然后把消息作為數據帶過去給A。A訂閱了就拿到了B數據。
? ? ? ? 語言說出來很難理解,但寫出來就很簡單。
????????
? ? ? ? 首先不在需要App組件定義state當中間人傳遞數據,外殼組件可以真正的作為外殼組件使用了。那樣就正常變成了,數據在那里,操作數據的方法就在那里。
????????
? ? ? ? List展示state,所以我們定義在List組件中。
????????
? ? ? ? Search組件來更新List組件里面的state,也就是說,
? ? ? ? 通過鉤子,也就是當頁面加載完畢,就啟動訂閱,然后接收的參數默認兩個,我們只需要后者,前者是消息名我們不需要就省略,消息名一致就可以訂閱到對應發布的數據,然后頁面將要關閉也就是卸載的時候,關閉訂閱方法。
? ? ? ? 然后就是Search組件在對應的時期通過PubSub.publish('me',{isLoading:false,users:response.data.items})把數據傳給訂閱的List組件。
????????
????????訂閱發布可以直接實現圖中勾選組件的數據傳輸,而不用一層層傳遞。
3.github搜索案例(fetch)
? ? ? ? 那么我們現在實現了通過axios庫(封裝的xhr)發生請求,現在我們去學一種新的發生請求fetch,不需要引入。
????????
? ? ? ? 這是截取某個文章的內容
????????
? ? ? ?中間的文字不需要在意,我們在意的是區別。不過我只學了前端,所以也暫且不用知道什么原理,只知道怎么用現在。
? ? ? ? 我們把前面axios對應的方法改成fetch
????????
? ? ? ?這個時候我們發現控制臺輸出的內容response并沒有我們想要的data數據。
????????
???????????????
? ? ? ? 如果寫成這樣,那么response就會包含我們的items。原理大概是--
????????
????????這里第一個.then為什么能用,因為fetch()是一個Promise實例對象,然后.then能鏈式使用,因為上一個.then返回的也是一個promise實例對象,這里的返回值指的是.then成功執行回調之后的返回值,而且返回值是一個response.json()也就是promise實例對象,如果.then指定的回調函數成功的返回值,是一個promise實例對象,那么這個promise實例對象就是整個.then方法的返回值,所以可以繼續調用.then 方法
????????首先第一個.then有兩個回調,成功的和失敗的。如果成功或者失敗的執行的回調函數的返回值是一個非promise值,那么外側的.then返回的promise實例狀態是成功的,值是返回的非promise值。如果返回的本身就是一個promise值,那么這個值就是外側.then所返回的promise實例的值,如果返回的是一個成功的promise實例而且值是1,那么.then返回的promise實例狀態成功而且值是1,如果返回的是一個pending狀態 的promise實例,那么外側的.then就是一個pending狀態的實例,如果異常,返回的promise狀態就是失敗的,原因就是拋出的異常
????????上面是知識點,大概是這些。我只是了解即可現在。
????????現在是實操,現在我們的返回值是一個response.json(),意味著這個當前的then返回值是一個promise實例,值和返回的promise.json()的值是一樣的,也就是我們可以繼續.then是因為上面的.then返回值是promise實例而且值也是promise.json()? ??
????????
????????
那么下一個.then執行response回調函數,用到promise實例對象值就是promise.json()
????????
? ? ? ? 這是第二次輸出response的結果,包含了我們想要的item。這里我們的error下了多次,實際上是沒必要的,我們優化一下。
????????
? ? ? ? 我們用.catch捕獲錯誤如果有的話,然后輸出錯誤。
????????
? ? ? ? 也可以這樣去寫,更加簡潔,這里的async異步函數,所以必須加await。但這樣可能出錯拿不到出錯。所以我們要這樣寫,
????????
? ? ? ? 這樣就也可以捕獲到錯誤并且輸出了。
? ? ? ? 通過這個搜索案例,里面的ref,props,以及PubSub訂閱,以及通過狀態的變化來驅動頁面進行交互功能,這些前端的思路是完全通的,axios,fetch這些請求,只能說能大概的知道這個案例種的使用方法。畢竟現在是在學前端,其他的還是可以放一放的。
????????