iT邦幫忙

2022 iThome 鐵人賽

DAY 22
0
Modern Web

跳脫MVC,Laravel + React 建立電商網站系列 第 22

Day 22 Laravel + React 實戰之路 -6商品詳細頁(前端)

  • 分享至 

  • xImage
  •  

今天我們要來進行商品詳細頁的撰寫,其實原理都差不多,所以話不多說,直接進入主題來實做看看吧!

接下來我們一樣來規畫整個畫面,我這邊先做畫面出來,先不丟資料~
我們先做一個ProductDetail,把一開始的畫面做出來
ProductDetail

export default function Home({product}){ 
    console.log(product); 
    return( 
        <div className="flex justify-center"> 
            <div className="pt-8 flex-col max-w-6xl"> 
                <div className="max-w-6xl flex justify-center"> 
                    <div className="w-6/12"> 
                        <img src="https://pic.616pic.com/ys_img/00/44/76/yYdFMozXJd.jpg" alt="商品圖片" /> 
                    </div> 
                    <div className="w-6/12 flex flex-col justify-around"> 
                        <p>商品名稱:測試123</p> 
                        <p className="font-bold text-lg text-red-600">價格:12000</p> 
                    </div> 
                </div> 
                <div className="max-w-6xl"> 
                    <h3>商品敘述</h3> 
                    <div> 
                        <p>這款蠟筆小新的頭,就是一顆頭,具有非常特別的效用</p> 
                        <p>看起來像蠟筆小新,實際上也是蠟筆小新</p> 
                    </div> 
                </div> 
            </div> 
        </div> 
    ); 
}

到這裡有基本的畫面了


小補充:
之前有說 我改的jsx都沒有hot reload到畫面上,要把npm run dev 關掉重開才會重新編譯,我今天找到問題了@@
vite.config.js 的地方 server 之中加入:

watch: {
    usePolling: true,
}

就解決這個問題惹!


現在我想在下面加入一些特別的東西,我想給畫面下面一個input type = number,然後可以即時的計算商品金額
然後我就在寫input的時候遇到了一個問題:在有設定value的情況下,input的改變會沒有反應。
原因就是因為"指定"了value ,這個時候input就變成了"受控組件(Controlled Component)",簡單來說就是會受到state以及setState的控制的Component。
這也導致了 「在只有指定value但沒有指定onChange事件的情況下,因為State並沒有更新,而導致DOM的值改變,但馬上又被react改變回來」。

那要怎麼解決這個問題呢?其實有兩種方式:
1. 如果這個input 不需要使用到state的這個特性的話,直接把value改成default value就可以使用了:

<div className="pt-2 max-w-6xl"> 
    <label>數量:</label> 
    <input type="number" defaultValue="1"/> 
    <p className="text-red-600">金額:12000</p> 
</div>

透過這樣的方式,讓這個Component從 受控組件變成 非(不)受控組件,如此一來會直接把使用者的輸入反映在畫面上。

2.但是我相信我們有一個共識,那就是:金額要跟著改變!!!所以我們還是要借助State的幫助:

export default function Home({product}){ 
    const [amount , setAmount] = useState(1); 
    function amountChange(e) 
    { 
        if(!isNaN(Math.round(e.target.value))) 
            setAmount(Math.round(e.target.value)); 
    } 
    return( 
        <div className="flex justify-center"> 
            <div className="pt-8 flex-col max-w-6xl"> 
                <div className="max-w-6xl flex justify-center"> 
                    <div className="w-6/12"> 
                        <img src="https://pic.616pic.com/ys_img/00/44/76/yYdFMozXJd.jpg" alt="商品圖片" /> 
                    </div> 
                    <div className="w-6/12 flex flex-col justify-around pl-3"> 
                        <p>商品名稱:測試123</p> 
                        <p className="font-bold text-lg text-red-600">價格:12000</p> 
                    </div> 
                </div> 
                <div className="max-w-6xl pt-2"> 
                    <h3>商品敘述</h3> 
                    <div> 
                        <p>這款蠟筆小新的頭,就是一顆頭,具有非常特別的效用</p> 
                        <p>看起來像蠟筆小新,實際上也是蠟筆小新</p> 
                    </div> 
                </div> 
                <div className="pt-2 max-w-6xl"> 
                    <label>數量:</label> 
                    <input type="number" value={amount} onChange={ amountChange }/> 
                    <p className="text-red-600">總金額:{12000 * amount}</p> 
                </div> 
            </div> 
        </div> 
    ); 
}

最後 我們再給一個去結帳的button(懶得做購物車了...XD)

<div className="pt-2 max-w-6xl text-center"> 
    <button className="inline-flex items-center px-3 py-2 border border-transparent text-sm leading-4 font-medium rounded-md text-gray-500 bg-indigo-50 hover:text-gray-700             focus:outline-none transition ease-in-out duration-150" > 
        結帳去 
    </button>
</div>

明天 我們再把後端建立完成就好了~


上一篇
Day 21 Laravel + React 實戰之路 -5(商品列表-後端資料修改)
下一篇
Day 23 Laravel + React 實戰之路 -6商品詳細頁(後端)
系列文
跳脫MVC,Laravel + React 建立電商網站30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言