千峰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.mzph.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函数绕过正则匹配绕过相…