第十八課:新篇章將api與clientSide網站UI介面連接
前一天我們完成了nodejs的Api架設,現在開始我們要讓網站介面與我們設置好的Api連接,做到真的互動式動態網站。
這邊我們要來完整一整個動態網站,讓網站介面不在是介面而是有綁Api動作,先打開一開始有實作到client Side的介面
這邊要先重要提醒,Api每次連接時就跟打開React App一樣要讓他在terminal使用npm start才會連上伺服器,到時候網站成行,我們要開啟忘網站也是要先讓Api連上伺服器,網站在npm start打開react app才會顯示整個網站該有的資訊。
都打開後我們可以先到clientSide開啟畫面與我們網站也打開在一旁操作,然後選擇我們先要來串接得部分。
所以首先要將我們寫好的ApiFolder與我們的Client串接,我們先需要了解Axios
大概了解Axios是我們串接第一步的媒介後,我們可以額外創建一個folder,並命明為hook folder與裡面是useFetch,裡面在使用Axios配合useEffect(不太清楚得話下面會講解)來fetchData(抓取資料)特別列出來的好處就是不用每次使用Api抓取資料都要寫一次axios,只需將useFetch folder來代表Axios就可以很簡潔的叫出資料,且這邊會有些小細節是app.get常常會需要不斷地抓取與更新資料,相較於app.post創建物件,網站功能最大的就是自動不間斷的抓區後端資料來更新頁面資訊,所以將會為了app.get特別創建一個useFetch的folder。
import React, { useEffect, useState } from 'react'
const useFetch = (url) => {
const [data, setData]=useState([]);//到時候axios要傳入的資料 先存放在useState內
const [loading,setLoading]=useState(false);//會紀錄連線中情況,之後方便有先載入介面
const [error, setError] =useState("");
//如網路錯誤或是url錯誤就會回報錯誤的useState
useEffect(()=>{
},[])
return {data,loading, error}
}
export default useFetch
useState最一開始講過了現在來介紹useEffect的效果與用法。
大概了解useEffect就是字面上的意思,等有動作後換useEffect函數執行的概念,我們可以在裡面寫入axios.get的函數,並會使用try{}catch{}與async函數搭配await變成的同步函數,原理就跟我們在使用在nodejs上的Api串接一樣,最重要得就是等await axios.get 抓取資料,其他回報都要先等他完成。
並我們把fetchData的內容先打上測試,會發現回報錯誤。
const fetchData = async()=>{
setLoading(true); //來確定連線時成功的開始
try{
const response = await axios.get(url);
//axios.get最重要的資料 且url是feature那邊傳入的/hotels
setData(resonse.data);
}catch(error){
setError(error)//如果有錯誤也紀錄進去setError State
}
setLoading(false);//代表連線時成功的結束
}
fetchData()
與feature component內的
const {data,loading,error} =useFetch("/hotels")
console.log(data)// 檢視有沒有叫入成功
並上述axios使用一樣要記得
npm i axios
import axios from "axios"
確認上述的axios是可以運作後,我們只要處理不同源的問題
http://localhost:3000/hotels
http://localhost:5000/api/v1/hotels
我們想要將後端測試Apihttp://localhost:3000 = http://localhost:5000/api/v1
所以我們可以用proxy來做上述的代理,來處理不同源問題(或是也可以一開始就設置一樣的測試loaclhost地址),但就怕會影響分頁等我們的Api設置,所以前後端分離的方式,雖然較麻煩有時候卻在管理上是必須的,到時候網站真的上線這邊就也要改成真實的網址。
"proxy": "http://localhost:5000/api/v1"
完成後我們可以看我們抓到的資料,並可以回到feature去把資料導進去
導入後應該會發生錯誤,錯誤是正常因為我們還沒有管理導入的資料
這邊將popularHotels資料修改後就可以完美的導入了。
<div className='popularHotels'>
{dataArray.map((item,index) =>
<Link to ={`/hotels/${item._id}`} style={{textDecoration:"none",color:"inherit"}} key={index} >
<div className="item" >
<img src={item.photos[0]} alt="" />
<div className="itemInfo">
<div className="title">
{item.name}
</div>
<div className="subTitle">
{item.city}
</div>
<div className="price">
TWD {item.cheapestPrice.toLocaleString()} 起
</div>
<div className="rate">
<button>{item.rating}</button>
<span>{item.rating >= 9.5 ? "好極了" : "傑出"}</span>
<p>{item.comments.toLocaleString()}則評論</p>
</div>
</div>
</div>
</Link>
)}
</div>
在原本的dataArrayMap列陣中,我們放入Link因為想要他到時候觸及該hotel就可以自動跳轉到我們相關的分頁且分頁url上也會傳入他的id,就跟那時候我們使用Api findById的概念去getHotel,我們到時候傳入的id就能幫助我們去做更詳細的該hotel資料顯示,並後面的style就是先前講的把有連結的特效給關掉。並在item div內有導入照片item.photo[0]代表是第一張,因為那時候我們一個hotel可以放入好幾張照片,所以取首張為代表圖。
完成後就恭喜你完成了第一次的從前端到後端的全端串接過程。
並且點擊還會自動跳轉到我們的hotel分頁,(link要記得import)
接下來就是延續的這股氣勢,我們要來做filter的與統計Api並且一條龍的從Api folder改到client side folder讓網站串接與運用axios的搭配越來越上手。這邊當然可以在component直接寫axios來抓資料,但因為我們的feature有一堆需要抓資料的飯店資訊,所以這次才特別練習拉出來並使用axios搭配useEffect的方式處理得更細緻。
並之後我們會ㄧ併再把它修成更符合的這裡的所規定的人氣民宿,並會在之後的Api進行 條件filter 與 統計上一併解說。
不知不覺競賽已經來到2/3左右,全端串連預計篇幅為Day18~26,並留最後三天講解TS與後台架設等規則,並本人在學習前、後端的體會時,為技術債會非常之大,邏輯與背誦,所以做筆記是必要的技能,前端的開發如何增加使用者體驗與後端的連接如何去把動作具象化等等,就跟考大考時的感受一樣,必須戰戰兢兢努力到一定程度才會開始看到成果,一開始只能先理解跟模仿,但到一定程度後,就會發現好像規則都是這樣,原則不變,變得只有更精進coding的精美程度,但不管怎麼說對所有開源者與創業者都至上最高的敬意,任何有成果的挑戰都是痛苦的,深知這點,所以為自己也為大家一起加油!