前言
六角學院的React入門工作坊進入第二週了,看到很多同學紛紛都將作業交上去了,我還不是很熟練,就很感謝DC同學分享自己的筆記與思路,才覺得我先前拆解同學的code分析成邏輯流程的方式是對的,然後自己重新在撰寫一次,這次也是一樣的模式!
大佈局:資料狀態 與 介面
在開始動工之前,先來思考會有什麼資料會需要使用到呢?不知道要放什麼資料,可以從功能開始,因為會有資料,就是因為有使用的需求呀!
產品列表
- 描述:需要有“產品原始資料”,我要運用這筆資料,將產品列表渲染到畫面上
- 設定資料狀態:
const [productList, setProductList] = useState()
- 功能:
- 根據畫面的“click”,會把被點擊的產品資料(id,品項,描述,價格)等資料丟到購物車中
- 點擊的品項,如果已經在購物車中了,就要把已存在在購物車資料中的該品項的數量資料+1
購物車列表
- 描述:會需要有“購物車資料”,一開始購物車資料是空陣列,因為還沒購物XD
設定資料狀態:
const [cart, setCart] = useState([]);
const [sum, setSum] = useState(0);
const [note, setNote] = useState(“”)
功能:
- 我們在點擊產品列表的某品項之後,該品項會被加入到“購物車資料”中,然後進行渲染購物車畫面
- 在購物車畫面的顯示裡,該品項除了產品的基本資料(id,品項名,描述,價格),在購物車資料中,要多定義“數量”與小計(數量*價格)
- 刪除按鈕:當我們不想要該品項時,可以透過刪除按鈕,將該品項刪除
- 更新數量:前面有敘述過,可以直接手動調整訂購的產品的數量
- 購物車品項的全部消費加總->需要定義資料狀態
const [sum, setSum] = useState(0);
- 備註也需要另外定義資料狀態c
onst [note, setNote] = useState(“”)
- 點擊送出訂單按鈕時,會將購物車資料帶到訂單畫面中
訂單列表
- 描述:會需要原始訂單資料,初始狀態是空陣列,接到從“購物車“送出按鈕後,送過來的資料
- 設定資料狀態:
const [order, setOrder] = useState([])
- 除了從購物車帶來的資料,要多定義一個id
介面的部分:
這次先純以“熟練React功能”為主,暫時先以bootstrap切版
撰寫程式邏輯
1-1 將產品資料渲染到畫面上
- App元件
- Menu元件,已經透過props將productList傳給Menu元件使用,透過資料驅動的方式將productList.map渲染到畫面上,記得要帶上key值
1-2 點擊畫面上的飲品時,會將資料帶入購物車
- 寫入購物車資料,預設為[]
const [cart, setCart] = useState([]);
- 點擊畫面上的飲品
- 為每個飲品,加入onClick事件->觸發函式addCart fn
- 撰寫函式addCart邏輯,addCart要帶入參數(product),也就是productList中的“被點擊的品項”,每個飲品都有可能被點擊,所以都加上
- 在addCart fn寫一個tempCart的新陣列,也就是為被點擊的品項做資料重組的動作,並給product帶入qty屬性預設值為1
- 為每個飲品,加入onClick事件->觸發函式addCart fn
addCart fn的流程設計
const addCart = (product) => { //短暫被加入的購物車資料(幫我做被點擊的品項的資料重組) const tempCart = [ ...cart, //[]帶入購物車原始資料,淺拷貝 { ...product,//帶入被點擊的品項原始資料 qty: 1, //給該品項資料增加qty屬性 //被帶入的品項數量預設都為1 } ] //寫入購物車資料 setCart(tempCart); }
App元件:圖片上cart的props其實不用帶入到Menu元件,因為Menu元件不會使用到
- Menu元件
- 加入購物車資料的console
1-3 將購物車資料渲染到畫面
- 購物車元件
1-4 判斷購物車是不是空的,切換畫面
- hint: 當然就需要透過購物車資料來判斷
- cart.length === 0 來判斷要顯示的畫面
- 這段在寫的時候一直出錯.後來才知道犯了JSX語法錯誤
1-5 重複點選飲品的判斷
當我在產品列表畫面點擊的品項,如果已經在購物車中了,就要把已存在在購物車資料中的該品項的數量資料+1
- 分析:點擊品項時,會先將該品項去跟購物車資料做判斷,判斷說是否已有該品項了
- 無該品項 -> 將該品項加入到購物車(本來就寫好的邏輯)
- 在購物車資料中用.find or .findIndex比對資料
- 這裡我們只需要知道"有或沒有"用.findIndex就好
- 沒有會回傳-1
- 有該品項 -> 更新該品項數量
- 重組tempCart的資料,將cart購物車資料拉出來比對是哪一項,
- 將該項資料的數量值更新值
- 無該品項 -> 將該品項加入到購物車(本來就寫好的邏輯)
1-6 購物車價格總計算
定義購物車商品的價格總計const [sum, setSum] = useState(0)
來總計商品的總價,然後透過useEffect來觀察購物車是否有更動,只要畫面更動就透過.reduce()方法來總計
- 記得要將sum透過props傳到購物車元件上
- 才能在購物車上渲染畫面
1-7 購物車品項手動select更改數量
這段功能是在描述,我可以在購物車清單畫面上手動的調整,該品項數量的select值,進而更新其他相關的值
我沒有在select標籤上綁value值,但沒有另外搭配onChange事件時,程式可以運作,但會一直出現紅字訊息如下,然後select區塊無法手動操作
首先,我在select上綁定value以及相關的資料狀態
給表單型態的標籤,加入onChange事件,撰寫函式updateCart程式邏輯並帶入參數(被更新的品項,e.target.value)
const updateCart = (updateItem, value) => {
//設置tempData來比對在購物車資料中哪一個品項被更新數量了
const tempData = cart.map((cartItem) => {
return cartItem.id === updateItem.id
? {
...cartItem,
qty: Number(value), //表單中所有的值都是字串需要轉型
}
: {...cartItem}
});
setCart(tempCart)
}
1-8 刪除購物車品項
當我們在購物車清單畫面上,點擊該品項前面的刪除按鈕,就可以刪除該品項,這裡會用.filter的方式寫:
- 要在按鈕上加入onClick事件,撰寫函式deleteCart刪除邏輯
note: cartItem.id !== deleteItem.id 只要該品項不等於[被點擊刪除按鈕的]品項,那個該品項就會被保留下來 - 這裡會需要轉想一下,但仔細想filter就是一個過濾器,只要“符合我們設定過濾器的條件”就會被回傳出來,也就是說會被留下來
const deleteCart = (deleteItem) => { const tempCart = cart.filter((cartItem) => cartItem.id !== deleteItem.id) setCart(tempCart) }
1-9 創建訂單(待捕)
甚麼是創建訂單呢?就是說,我在購物車畫面上,已經選購好商品,就點擊購物車列表的按鈕,所以要設置onClick事件,觸發函式:createOrder
會需要定義資料const [order, setOrder] = useState([]);以及const [note, setNote] = useState([]);
- 還需要設置:在備註的表單上取的e.target.value備註 value的值
- 所以訂單上,我們會需要什麼資料?
- 新的id:代表該筆訂單
- 購物車資料cart
- 備註資料note
- 總價格sum
- 最後,生出訂單後,我們要清空購物車以及備註欄位
1-10 將訂單資料渲染到畫面上
這裡購物車開始的邏輯很像,就是先判斷order.length === 0
判斷訂單資料是不是空的:
如果是就顯示尚未建立訂單
如果不是就直接渲染資料 -> 資料驅動