千峰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.rhkb.cn/news/26586.html

    如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

    相关文章

    C语言【指针篇】(四)

    前言&#xff1a;正文1. 字符指针变量2. 数组指针变量2.1 数组指针变量是什么?2.2 数组指针变量怎么初始化 3. 二维数组传参的本质4. 函数指针变量4.1 函数指针变量的创建4.2 函数指针变量的使用4.3 两段有趣的代码4.3.1 typedef关键字 5. 函数指针数组6. 转移表 总结 前言&am…

    GitCode 助力 python-office:开启 Python 自动化办公新生态

    项目仓库&#xff1a;https://gitcode.com/CoderWanFeng1/python-office 源于需求洞察&#xff0c;打造 Python 办公神器 项目作者程序员晚枫在运营拥有 14w 粉丝的 B 站账号 “Python 自动化办公社区” 时&#xff0c;敏锐察觉到非程序员群体对 Python 学习的强烈需求。在数字…

    对话Stack Overflow,OceanBase CTO 杨传辉谈分布式数据库的“前世今生”

    近日&#xff0c; OceanBase CTO 杨传辉受邀出席全球知名开发者论坛 Stack Overflow 的最新一期播客节目&#xff0c;与 Stack Overflow 高级内容创作官 Ryan Donovan 展开对话。双方围绕分布式数据库的可靠性、一致性保障、HTAP 架构以及 AI 时代分布式数据库的发展趋势等热点…

    小结:计算机网路中的性能指标小结

    发现B站的这套课程不错&#xff0c;开始学习并笔记之&#xff1a;计算机网络微课堂&#xff08;有字幕无背景音乐版&#xff09;_哔哩哔哩_bilibili 1) 速率 2) 带宽 3) 吞吐量 带宽1 Gb/s的以太网&#xff0c;代表其额定速率是1 Gb/s&#xff0c;这个数值也…

    seasms v9 注入漏洞 + order by注入+​information_schema​解决方法

    目录 一、当注入时&#xff0c;information_schema被禁用的解决方法 1.通过sys库可以获取到表名和库名 2.通过无列名注入join获取列名 二、seasms v9 注入漏洞 三、order by注入 一、当注入时&#xff0c;information_schema被禁用的解决方法 information_schema数据库是My…

    FFmpeg-chapter2-C++中的线程

    1 常规的线程 一般常规的线程如下所示 // CMakeProject1.cpp: 定义应用程序的入口点。 //#include "CMakeProject1.h" #include <thread> using namespace std;void threadFunction(int index) {for (int i 0; i < 1000; i){std::cout << "Th…

    【华三】从零开始掌握SR技术:原理、架构与应用全解析

    【华三】从零开始掌握SR技术&#xff1a;原理、架构与应用全解析 一、初识SR&#xff1a;路由技术的新革命1.1 传统网络的困扰&#xff1a;从真实案例看技术瓶颈1.1.1 企业网络运维之痛问题2&#xff1a;流量工程实现困难问题3&#xff1a;网络智能化缺失 1.2 SR的诞生意义&…

    CogBlobTool工具

    CogBlobTool是一款专用于图像斑点检测于分析的 工具&#xff0c;通过灰度值阈值分割和特征过滤&#xff0c;帮助在复杂背景中提取目标区域&#xff0c;并计算几何属性。 效果图 注意&#xff1a;在这里只有一张图像可以不使用模板匹配工具 CogBlobTool工具的功能 斑点检测于…

    大模型应用案例 | 大模型+金融运维,擎创携手某证券创新运维能力新范式

    一、当大模型遇上金融运维&#xff1a;一场让告警处理“脱胎换骨”的变革 2022年底&#xff0c;ChatGPT的横空出世让AI技术彻底出圈&#xff1b;短短两年后&#xff0c;大模型已悄然潜入金融行业的“心脏地带”——运维系统。面对指数级暴增的告警信息、碎片化的处理流程&#…

    Linux三种网络方式

    前言 发现运维啥都得会&#xff0c;这周就遇到了网络问题自己无法解决&#xff0c;因此痛定思痛学一下。 参考文献 你管这破玩意叫网络&#xff1f; 桥接模式、NAT模式、仅主机模式&#xff0c;原来是这样工作的 交换机 构成局域网&#xff0c;实现所有设备之间的通信。 …

    基于PHP和MySQL的用户登录注册系统实现

    系统架构 系统采用前后端分离的架构&#xff0c;使用PHP作为后端语言&#xff0c;MySQL作为数据库。以下是系统的整体架构图&#xff1a; 这个架构图展示了系统的三个主要层次&#xff1a; 前端界面层&#xff1a;包含用户交互的三个页面&#xff08;注册、登录和欢迎页面&am…

    脚本无法获取响应主体(原因:CORS Missing Allow Credentials)

    背景&#xff1a; 前端的端口号8080&#xff0c;后端8000。需在前端向后端传一个参数&#xff0c;让后端访问数据库去检测此参数是否出现过。涉及跨域请求&#xff0c;一直有这个bug是404文件找不到。 在修改过程当中不小心删除了一段代码&#xff0c;出现了这个bug&#xff0…

    【计网】计算机网络概述

    第一章 计算机网络概述 1.2 因特网概述1.2.1 网络、互联网和因特网1.2.2 因特网发展的三个阶段1.2.3 因特网的标准化工作1.2.4 因特网的组成 1.3 三种交换方式1.3.1 电路交换1.3.2 分组交换1.3.3 报文交换1.3.4 三种交换的对比 1.4 计网的定义与分类1.4.1 定义1.4.2 分类 1.5 计…

    前端依赖nrm镜像管理工具

    npm 默认镜像 &#xff1a;https://registry.npmjs.org/ 1、安装 nrm npm install nrm --global2、查看镜像源列表 nrm ls3、测试当前环境下&#xff0c;哪个镜像源速度最快。 nrm test4、 切换镜像源 npm config get registry # 查看当前镜像源 nrm use taobao # 等价于 npm…

    LinkedList与链表

    目录 1、链表 2、实现自己的链表 (不带头结点) 2.1、遍历链表 2.2、求链表长度 2.3、判断链表是否包含关键字 2.4、插入节点 2.5、任意位置插入一个节点 2.6、删除一个节点 2.7、删除所有值为key的节点 2.8、清空所有节点 1、链表 链表是一种物理结构上不连续的存储结…

    StableDiffusion打包 项目迁移 项目分发 1

    文章目录 SD项目迁移前置知识webui-user.batwebui.batlaunch_utils.py 下一篇开始实践 SD项目迁移 显卡驱动更新&#xff1a;https://www.nvidia.cn/geforce/drivers/ 下载安装三个程序&#xff1a; python3.10.6: https://www.python.org/downloads/release/python-3106/gi…

    架构案例:从初创互联网公司到分布式存储与反应式编程框架的架构设计

    文章目录 引言一、初创互联网公司架构演化案例1. 万级日订单级别架构2. 十万级日订单级别架构3. 百万级日订单级别架构 二、分布式存储系统 Doris 架构案例三、反应式编程框架架构案例总结 引言 分布式架构 今天我们将探讨三种不同类型的架构案例&#xff0c;分别探讨 一个初…

    Xshell客户端免费版无需注册Linux连接客户端8.0详细安装教程(2025年最全最详细的图文教程)附安装包

    目录 关联链接 前言 一、下载安装程序 二、安装Xshell客户端 1.启动安装 2.下一步 3.许可协议 4.安装目录 5.开始安装 6.安装完成 7.免费许可 8.大功告成&#xff01; 关联链接 Xftp免费客户端安装教程&#xff1a;https://blog.csdn.net/xiaoguo1001/article/detai…

    electron多进程通信

    进程间通信 | Electron 进程间通信 (IPC) 是在 Electron 中构建功能丰富的桌面应用程序的关键部分之一。 由于主进程和渲染器进程在 Electron 的进程模型具有不同的职责&#xff0c;因此 IPC 是执行许多常见任务的唯一方法&#xff0c;例如从 UI 调用原生 API 或从原生菜单触发…

    登录日志管理:通用分页和排序封装、 查询登录日志列表、删除登录日志、清空登录日志、解锁用户登录状态(解锁密码错误次数超限)

    文章目录 引言I 登录日志管理接口列表II 通用分页和排序封装Java 分页和排序封装vue前端排序页面III 工具类字段名转换 : 驼峰转下划线命名引言 I 登录日志管理 接口列表 import request from @/utils/request// 查询登录日志列表 export function list(query) {return