千峰React:案例二

完成對html文檔還有css的引入,引入一下數據:

import { func } from 'prop-types'
import './購物車樣式.css'
import axios from 'axios'
import { useImmer } from 'use-immer'
import { useEffect } from 'react'function Item() {return (<li className='active'><h3>香蕉</h3><p>單價:5</p><p>數量:<span className='remove'>-</span><span>1</span><span className='add'>+</span></p><div className='cartbtn'>取消購買</div></li>)
}function Cart() {const [list, setList] = useImmer([])useEffect(() => {axios.get('../public/cartData.json').then((res) => {console.log(res)})})return (<div className='cart'><ul><Item /></ul><div className='all'>總金額:<span>5</span>元</div></div>)
}
export default Cart

然后判斷數據是否存在:

剛剛數字一直在瘋漲,導致他瘋漲的原因是我的useEffect沒加依賴數組,還有axios的url,如果我的數據文件在public里,可以直接從根目錄訪問(好像學過),要寫成這樣👇

useEffect(() => {axios.get('/cartData.json').then((res) => {if (res.data.errcode === 0) {//map來給購物車添加setList(res.data.list.map((item) => ({...item,active:false})))}})},[])

還有一個無語的bug是箭頭函數的return每次都會加大括號忘記加retuen,不加return又會格式化到下一行

對每個按鈕綁上onClick事件,再給每個按鈕綁上id:

import { func } from 'prop-types'
import './購物車樣式.css'
import axios from 'axios'
import { useImmer } from 'use-immer'
import { useEffect } from 'react'function Item({id,name,price,number,active,handleAdd}) {return (//active初始根據active的值判定<li className={ active?'active':''}><h3>{ name}</h3><p>單價:{ price}</p><p>數量:<span className='remove'>-</span><span>{ number}</span><span className='add'>+</span></p><div className='cartbtn' onClick={()=>handleAdd(id)}>{ active?'取消購買':'添加購物車'}</div></li>)
}function Cart() {const [list, setList] = useImmer([])useEffect(() => {axios.get('/cartData.json').then((res) => {if (res.data.errcode === 0) {//map來給購物車添加setList(res.data.list.map((item) => ({ ...item, active: false })))}})}, [])const handleAdd=(id) => {setList((draft) => {const value = draft.find((item) => item.id === id)value.active=!value.active})}return (<div className='cart'><ul>{list.map((item) => <Item key={item.id} {...item} handleAdd={handleAdd} />)}</ul><div className='all'>總金額:<span>5</span>元</div></div>)
}
export default Cart

    增加修改數量的功能

    import { func } from 'prop-types'
    import './購物車樣式.css'
    import axios from 'axios'
    import { useImmer } from 'use-immer'
    import { useEffect } from 'react'function Item({id,name,price,number,active,handleAdd,handleNumberChange,
    }) {return (//active初始根據active的值判定<li className={active ? 'active' : ''}><h3>{name}</h3><p>單價:{price}</p><p>數量:<span className='remove' onClick={()=>handleNumberChange(id, -1)}>-</span><span>{number}</span><span className='add' onClick={()=>handleNumberChange(id, +1)}>+</span></p><div className='cartbtn' onClick={() => handleAdd(id)}>{active ? '取消購買' : '添加購物車'}</div></li>)
    }function Cart() {const [list, setList] = useImmer([])useEffect(() => {axios.get('/cartData.json').then((res) => {if (res.data.errcode === 0) {//map來給購物車添加setList(res.data.list.map((item) => ({ ...item, active: false })))}})}, [])const handleAdd = (id) => {setList((draft) => {const value = draft.find((item) => item.id === id)value.active = !value.active})}const handleNumberChange = (id, num) => {setList((draft) => {const value = draft.find((item) => item.id === id)if (value.number === 0 && num < 0) {return}value.number += num})}return (<div className='cart'><ul>{list.map((item) => (<Itemkey={item.id}{...item}handleAdd={()=>handleAdd(item.id)}handleNumberChange={(num)=>handleNumberChange(item.id,num)}//注意傳參問題,前面的num是onClick傳遞的/>))}</ul><div className='all'>總金額:<span>5</span>元</div></div>)
    }
    export default Cart
    

    如果你寫成?handleNumberChange={() => handleNumberChange(item.id, num)}num?的值無法動態傳遞,因為?num?是在?Item?組件的?onClick?事件中才確定的。

    加入計算總金額功能,用filter選擇被加入購物車的商品,reduce計算

     const all = list.filter((item) => item.active).reduce((init, item) => init + item.number * item.price, 0)

    每次改變狀態時都會重新渲染,提升性能,使用memo,只有props不同的時候才會渲染

    里面包的是函數,之前學的useCallback可以解決函數被Object.Is()判別為不同的問題

    import { func } from 'prop-types'
    import './購物車樣式.css'
    import axios from 'axios'
    import { useImmer } from 'use-immer'
    import { memo, useCallback, useEffect } from 'react'const Item = memo(function Item({id,name,price,number,active,handleAdd,handleNumberChange,
    }) {console.log('如果被渲染了,我就會出現')return (//active初始根據active的值判定<li className={active ? 'active' : ''}><h3>{name}</h3><p>單價:{price}</p><p>數量:<span className='remove' onClick={() => handleNumberChange(id, -1)}>-</span><span>{number}</span><span className='add' onClick={() => handleNumberChange(id, +1)}>+</span></p><div className='cartbtn' onClick={() => handleAdd(id)}>{active ? '取消購買' : '添加購物車'}</div></li>)
    })function Cart() {const [list, setList] = useImmer([])const all = list.filter((item) => item.active).reduce((init, item) => init + item.number * item.price, 0)useEffect(() => {axios.get('/cartData.json').then((res) => {if (res.data.errcode === 0) {//map來給購物車添加setList(res.data.list.map((item) => ({ ...item, active: false })))}})}, [])const handleAdd = useCallback((id) => {setList((draft) => {const value = draft.find((item) => item.id === id)value.active = !value.active})})const handleNumberChange = useCallback((id, num) => {setList((draft) => {const value = draft.find((item) => item.id === id)if (value.number === 0 && num < 0) {return}value.number += num})})return (<div className='cart'><ul>{list.map((item) => (<Itemkey={item.id}{...item}handleAdd={() => handleAdd(item.id)}handleNumberChange={(num) => handleNumberChange(item.id, num)} //注意傳參問題,前面的num是onClick傳遞的/>))}</ul><div className='all'>總金額:<span>{all}</span>元</div></div>)
    }
    export default Cart
    

    這下基本就寫完了

    本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
    如若轉載,請注明出處:http://www.pswp.cn/web/70973.shtml
    繁體地址,請注明出處:http://hk.pswp.cn/web/70973.shtml
    英文地址,請注明出處:http://en.pswp.cn/web/70973.shtml

    如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

    相關文章

    用DeepSeek生成批量刪除處理 PDF第一頁工具

    安裝依賴庫 在運行程序之前&#xff0c;請確保安裝所需的庫&#xff1a; pip install pymupdf python-docx Python 程序代碼 import os import fitz # PyMuPDF from docx import Documentdef delete_pdf_first_page(input_path, output_path):"""刪除 PDF…

    redis的下載和安裝詳解

    一、下載redis安裝包 進入redis官網查看當前穩定版本&#xff1a; https://redis.io/download/發現此時的穩定版本是6.2.4&#xff0c; 此時可以去這個網站下載6.2.4穩定版本的tar包。 暫時不考慮不在windows上使用redis&#xff0c;那樣將無法發揮redis的性能 二、上傳tar…

    如何使用 Jenkins 實現 CI/CD 流水線:從零開始搭建自動化部署流程

    如何使用 Jenkins 實現 CI/CD 流水線:從零開始搭建自動化部署流程 在軟件開發過程中,持續集成(CI)和持續交付(CD)已經成為現代開發和運維的標準實踐。隨著代碼的迭代越來越頻繁,傳統的手動部署方式不僅低效,而且容易出錯。為了提高開發效率和代碼質量,Jenkins作為一款…

    Python基于Django的網絡課程在線學習平臺【附源碼】

    博主介紹&#xff1a;?Java老徐、7年大廠程序員經歷。全網粉絲12w、csdn博客專家、掘金/華為云/阿里云/InfoQ等平臺優質作者、專注于Java技術領域和畢業項目實戰? &#x1f345;文末獲取源碼聯系&#x1f345; &#x1f447;&#x1f3fb; 精彩專欄推薦訂閱&#x1f447;&…

    Pytorch為什么 nn.CrossEntropyLoss = LogSoftmax + nn.NLLLoss?

    為什么 nn.CrossEntropyLoss LogSoftmax nn.NLLLoss&#xff1f; 在使用 PyTorch 時&#xff0c;我們經常聽說 nn.CrossEntropyLoss 是 LogSoftmax 和 nn.NLLLoss 的組合。這句話聽起來簡單&#xff0c;但背后到底是怎么回事&#xff1f;為什么這兩個分開的功能加起來就等于…

    rabbitmq 延時隊列

    要使用 RabbitMQ Delayed Message Plugin 實現延時隊列&#xff0c;首先需要確保插件已安裝并啟用。以下是實現延時隊列的步驟和代碼示例。 1. 安裝 RabbitMQ Delayed Message Plugin 首先&#xff0c;確保你的 RabbitMQ 安裝了 rabbitmq-delayed-message-exchange 插件。你可…

    在 Vue 單文件組件(SFC)中,標簽的顯式關閉與隱式關閉有著重要的區別

    一、顯式關閉標簽 1、定義&#xff1a; 所有的 HTML 標簽都必須有一個對應的結束標簽。 自閉合標簽也必須使用 / 來關閉。 <template> <div> <p>這是一個段落</p> <img src"image.png"…

    第四屆大數據、區塊鏈與經濟管理國際學術會議

    重要信息 官網&#xff1a;www.icbbem.com 時間&#xff1a;2025年3月14-16日 地點&#xff1a;中國-武漢 &#xff08;線上召開&#xff09; 簡介 第四屆大數據、區塊鏈與經濟管理國際學術會議(ICBBEM 2025)&#xff0c;將于2025年3月14-16日在中國湖北省武漢市召開。…

    每日十個計算機專有名詞 (7)

    Metasploit 詞源&#xff1a;Meta&#xff08;超越&#xff0c;超出&#xff09; exploit&#xff08;漏洞利用&#xff09; Metasploit 是一個安全測試框架&#xff0c;用來幫助安全專家&#xff08;也叫滲透測試人員&#xff09;發現和利用計算機系統中的漏洞。你可以把它想…

    使用Docker Compose部署 MySQL8

    MySQL 8 是一個功能強大的關系型數據庫管理系統,而 Docker 則是一個流行的容器化平臺。結合使用它們可以極大地簡化 MySQL 8 的部署過程,并且確保開發環境和生產環境的一致性。 安裝 Docker 和 Docker Compose 首先,確保你的機器上已經安裝了 Docker 和 Docker Compose。 …

    mamba_ssm和causal-conv1d詳細安裝教程

    1.前言 Mamba是近年來在深度學習領域出現的一種新型結構&#xff0c;特別是在處理長序列數據方面表現優異。在本文中&#xff0c;我將介紹如何在 Linux 系統上安裝并配置 mamba_ssm 虛擬環境。由于官方指定mamba_ssm適用于 PyTorch 版本高于 1.12 且 CUDA 版本大于 11.6 的環境…

    c++中初始化列表的使用

    在 C 中&#xff0c;初始化列表是在構造函數的定義中&#xff0c;用于對類的成員變量進行初始化的一種方式。它緊跟在構造函數的參數列表之后&#xff0c;使用冒號 : 分隔&#xff0c;各成員變量的初始化用逗號 , 分隔。下面詳細介紹初始化列表及其參數的含義。 基本語法 clas…

    《Linux系統編程篇》System V信號量實現生產者與消費者問題(Linux 進程間通信(IPC))——基礎篇(拓展思維)

    文章目錄 &#x1f4da; **生產者-消費者問題**&#x1f511; **問題分析**&#x1f6e0;? **詳細實現&#xff1a;生產者-消費者****步驟 1&#xff1a;定義信號量和緩沖區****步驟 2&#xff1a;創建信號量****步驟 3&#xff1a;生產者進程****步驟 4&#xff1a;消費者進程…

    利用 Python 爬蟲進行跨境電商數據采集

    1 引言2 代理IP的優勢3 獲取代理IP賬號4 爬取實戰案例---&#xff08;某電商網站爬取&#xff09;4.1 網站分析4.2 編寫代碼4.3 優化代碼 5 總結 1 引言 在數字化時代&#xff0c;數據作為核心資源蘊含重要價值&#xff0c;網絡爬蟲成為企業洞察市場趨勢、學術研究探索未知領域…

    HONOR榮耀MagicBook 15 2021款 獨顯(BOD-WXX9,BDR-WFH9HN)原廠Win10系統

    適用型號&#xff1a;【BOD-WXX9】 MagicBook 15 2021款 i7 獨顯 MX450 16GB512GB (BDR-WFE9HN) MagicBook 15 2021款 i5 獨顯 MX450 16GB512GB (BDR-WFH9HN) MagicBook 15 2021款 i5 集顯 16GB512GB (BDR-WFH9HN) 鏈接&#xff1a;https://pan.baidu.com/s/1S6L57ADS18fnJZ1…

    c語言實現三子棋小游戲(涉及二維數組、函數、循環、常量、動態取地址等知識點)

    使用C語言實現一個三子棋小游戲 涉及知識點&#xff1a;二維數組、自定義函數、自帶函數庫、循環、常量、動態取地址等等 一些細節點&#xff1a; 1、引入自定義頭文件&#xff0c;需要用""雙引號包裹文件名&#xff0c;目的是為了和官方頭文件的<>區分開。…

    C語言數據類型及其使用 (帶示例)

    目錄 1. 基本數據類型 整型 浮點型 字符型 2. 構造數據類型 數組 結構體 聯合體&#xff08;共用體&#xff09; 枚舉類型 3. 指針類型 4. 空類型 在 C 語言中&#xff0c;數據類型是非常重要的概念&#xff0c;它決定了數據在內存中的存儲方式、占用空間大小以及可…

    Web自動化之Selenium添加網站Cookies實現免登錄

    在使用Selenium進行Web自動化時&#xff0c;添加網站Cookies是實現免登錄的一種高效方法。通過模擬瀏覽器行為&#xff0c;我們可以將已登錄狀態的Cookies存儲起來&#xff0c;并在下次自動化測試或爬蟲任務中直接加載這些Cookies&#xff0c;從而跳過登錄步驟。 Cookies簡介 …

    NAT 技術:網絡中的 “地址魔術師”

    目錄 一、性能瓶頸&#xff1a;NAT 的 “阿喀琉斯之踵” &#xff08;一&#xff09;數據包處理延遲 &#xff08;二&#xff09;高并發下的性能損耗 二、應用兼容性&#xff1a;NAT 帶來的 “適配難題” &#xff08;一&#xff09;端到端通信的困境 &#xff08;二&…

    php序列化與反序列化

    文章目錄 基礎知識魔術方法&#xff1a;在序列化和反序列化過程中自動調用的方法什么是 __destruct() 方法&#xff1f;何時觸發 __destruct() 方法&#xff1f;用途&#xff1a;語法示例&#xff1a; 反序列化漏洞利用前提條件一些繞過策略繞過__wakeup函數繞過正則匹配繞過相…