loading为什么不更新
场景:封装好的弹框,按钮上加了个loading状态,根据传入的值弹框提交的模块内容不一样。loading更新过后,但是值没有变。
注)写法一loading不更新,写法二loading值更新。
一、写法一
写法一中的 acceptanceReject 函数是一个异步函数,它会在异步操作完成后才会执行 finally 中的代码。这意味着 finally 中的 setLoading(false) 会在 acceptanceReject 函数中所有异步操作完成后才执行,包括 await rejectDataDs.current?.validate()、await getTaskId(instanceId) 和 await postAcceptance(params)。
因此,在写法一中,即使在 acceptanceReject 函数中设置了 setLoading(true),但在 handleSubmit 函数中并没有等待 acceptanceReject 函数中的异步操作完成,所以在 handleSubmit 中立即打印 loading 时,可能仍然是旧值。
/** 提交 */const handleSubmit = () => {switch (type) {case 'one': oneReject();break;case 'two': twoReject();break;case 'three': fourReject();break;default:break;}};const one= async () => {setLoading(true);try {const validate = await rejectDataDs.current?.validate();if (!validate) {return;}console.log('执行了嘛');const { id, instanceId } = formDataDs.current?.toData();const taskIdValue = await getTaskId(instanceId);const params: ItemAcceptance = {...rejectDataDs.current?.toData(),id,instanceId,approveResult: 'N',taskId: taskIdValue?.[0]?.taskId,};debuggerconst res = await postAcceptance(params);handleSuccess(res, 'acceptanceReject');} finally {setLoading(false);}};const two= async () => {const { id, instanceId } = formDataDs.current?.toData();const { approveOpinion } = rejectDataDs.current?.toData();const taskIdValue = await getTaskId(instanceId);const params: DetermineParams = {id,taskId: taskIdValue?.[0]?.taskId,instanceId,approveOpinion,approveResult: 'N',};const res = await postDetermine(params);handleSuccess(res, 'decideReject');};const three= async () => {const {id,pkNo,instanceId,subInstanceId,} = formDataDs.current?.toData();const { approveOpinion } = rejectDataDs.current?.toData();const taskIdValue = await getTaskId(subInstanceId);const params: ApprovalParams = {id,pkNo,taskId: taskIdValue?.[0]?.taskId,instanceId,subInstanceId,approveResult: 'N',approveOpinion,};const res = await postApprove(params);handleSuccess(res, 'approveReject');};
解决方法:因为switch中忘记加异步await了。
二:写法二
写法二中,所有异步操作都在同一个函数中,因此 setLoading(true) 和后续的异步操作是连续执行的,所以可以在后续代码中获取到正确的 loading 值。
const handleSubmit = async () => {setLoading(true);try {const validate = await rejectDataDs.current?.validate();if (!validate) {return;}const { id, instanceId } = formDataDs.current?.toData();const taskIdValue = await getTaskId(instanceId);const params: ItemAcceptance = {...rejectDataDs.current?.toData(),id,instanceId,approveResult: 'N',taskId: taskIdValue?.[0]?.taskId,};console.log('loading', loading);const res = await postAcceptance(params);handleSuccess(res, 'acceptanceReject');} finally {setLoading(false);}};
三、完整代码(问题版本)
封装好的完整代码如下:
import {ApprovalParams,DetermineParams,ItemAcceptance,
} from '@/interface/channelPk/main';
import { languageConfig } from '@/language/language';
import { Button, Form, message, Modal, TextArea } from 'choerodon-ui/pro';
import DataSet from 'choerodon-ui/dataset/data-set/DataSet';
import React, { useEffect, useState } from 'react';
import { LabelLayout } from 'choerodon-ui/pro/lib/form/enum';
import { ButtonColor } from 'choerodon-ui/pro/lib/button/enum';
import {postAcceptance,postApprove,postDetermine,
} from '@/api/channelPk/main';
import {getTaskId,handleCancel,pubPath,
} from '@/pages/channelPk/detail/hook';
import { FieldType } from 'choerodon-ui/dataset/data-set/enum';
import { useHistory } from 'dva';
import { set } from 'choerodon-ui/dataset/object-chain-value';interface HandleRejectProps {visible: boolean;setVisible: (val: boolean) => void;formDataDs: DataSet;type: string;
}let modal: any;
const RejectModel: React.FC<HandleRejectProps> = ({visible,formDataDs,type,setVisible,
}) => {let history = useHistory();const [loading, setLoading] = useState(false);/** ds 驳回 */const rejectDataDs = new DataSet({autoCreate: true,fields: [{name: 'approveOpinion',type: FieldType.string,label: languageConfig('rejectReason', '驳回原因'),placeholder: languageConfig('planceholder.rejectReason','请输入驳回原因',),required: true,},],});useEffect(() => {if (visible) {openModal();}}, [visible]);/** 弹框打开 */const openModal = () => {modal = Modal.open({title: languageConfig('btn.reject', '驳回'),okText: languageConfig('btn.confirm', '确定'),closable: true,children: <Box />,footer: (<div style={{ textAlign: 'right' }}><Buttonloading={loading}color={ButtonColor.primary}onClick={() => handleSubmit()}>{languageConfig('btn.confirm', '确定')}</Button><Buttonloading={loading}onClick={() => {modal.close();setVisible(false);}}>{languageConfig('btn.cancel', '取消')}</Button></div>),});};/** 内容 */const Box = () => {return (<div className="ltc-c7n-style"><div className="customer"><div className="border"></div><FormdataSet={rejectDataDs}labelWidth={80}columns={4}labelLayout={LabelLayout.vertical}className="reject"><TextAreaname="approveOpinion"rows={4}colSpan={4}newLine={true}// maxLength={200}showLengthInfoclearButton/></Form></div></div>);};/** 提交 */const handleSubmit = async () => {const validate = await rejectDataDs.current?.validate();if (!validate) {return;}setLoading(true);switch (type) {case 'acceptance': // 受理驳回await acceptanceReject();break;case 'decide': // 判定驳回await decideReject();break;case 'one': // 战区内未确权-一级审批await oneReject();break;case 'two': // 战区内未确权-二级审批await twoReject();break;case 'four': // 战区内已确权-二级审批await fourReject();break;case 'seven': // 跨战区await sevenReject();break;default:break;}};/** 【受理】驳回 */const acceptanceReject = async () => {const { id, instanceId } = formDataDs.current?.toData();const taskIdValue = await getTaskId(instanceId);const params: ItemAcceptance = {...rejectDataDs.current?.toData(),id,instanceId,approveResult: 'N',taskId: taskIdValue?.[0]?.taskId,};const res = await postAcceptance(params);handleSuccess(res, 'acceptanceReject');};/** 【判定】驳回(跨战区) */const decideReject = async () => {const { id, instanceId } = formDataDs.current?.toData();const { approveOpinion } = rejectDataDs.current?.toData();const taskIdValue = await getTaskId(instanceId);const params: DetermineParams = {id,taskId: taskIdValue?.[0]?.taskId,instanceId,approveOpinion,approveResult: 'N',};const res = await postDetermine(params);handleSuccess(res, 'decideReject');};/** 【战区内未确权-一级审批】驳回 */const oneReject = async () => {const {id,pkNo,instanceId,subInstanceId,} = formDataDs.current?.toData();const { approveOpinion } = rejectDataDs.current?.toData();const taskIdValue = await getTaskId(subInstanceId);const params: ApprovalParams = {id,pkNo,taskId: taskIdValue?.[0]?.taskId,instanceId,subInstanceId,approveResult: 'N',approveOpinion,};const res = await postApprove(params);handleSuccess(res, 'approveReject');};/** 【战区内未确权-二级审批】驳回 */const twoReject = async () => {const {id,pkNo,instanceId,subInstanceId,} = formDataDs.current?.toData();const { approveOpinion } = rejectDataDs.current?.toData();const taskIdValue = await getTaskId(subInstanceId);const params: ApprovalParams = {id,pkNo,taskId: taskIdValue?.[0]?.taskId,subInstanceId,instanceId,approveOpinion,approveResult: 'N',};const res = await postApprove(params);handleSuccess(res, 'approveReject');};/** 【战区内已确权-二级审批-一致】驳回 */const fourReject = async () => {const {id,pkNo,instanceId,subInstanceId,} = formDataDs.current?.toData();const { approveOpinion } = rejectDataDs.current?.toData();const taskIdValue = await getTaskId(subInstanceId);const params: ApprovalParams = {id,pkNo,taskId: taskIdValue?.[0]?.taskId,subInstanceId,instanceId,approveOpinion,approveResult: 'N',};const res = await postApprove(params);handleSuccess(res, 'approveReject');};/** 【跨战区-审批】:驳回 */const sevenReject = async () => {const {channelRemoveId,pkNo,subInstanceId,instanceId,} = formDataDs.current?.toData();const { approveOpinion } = rejectDataDs.current?.toData();const taskIdValue = await getTaskId(subInstanceId);const params: ApprovalParams = {id: channelRemoveId,pkNo,taskId: taskIdValue?.[0]?.taskId,subInstanceId,instanceId,approveOpinion,approveResult: 'N',};const res = await postApprove(params);handleSuccess(res, 'approveReject');};/** 公共:回调 */const handleSuccess = (res: any, kind: string) => {setLoading(false);if (res === '操作成功!') {message.success(res, undefined, undefined, 'top');modal.close();handleCancel();history.replace(`${pubPath}/success?from=${kind}`);} else {message.warning(res.message, undefined, undefined, 'top');}};return <></>;
};export default RejectModel;
相关文章:
loading为什么不更新
场景:封装好的弹框,按钮上加了个loading状态,根据传入的值弹框提交的模块内容不一样。loading更新过后,但是值没有变。 注)写法一loading不更新,写法二loading值更新。 一、写法一 写法一中的 acceptanc…...
Rust 力扣 - 1652. 拆炸弹
文章目录 题目描述题解思路题解代码题目链接 题目描述 题解思路 我们只需要遍历长度长度为k的窗口,然后把窗口内数字之和填充到结果数组中的对应位置即可 题解代码 impl Solution {pub fn decrypt(code: Vec<i32>, k: i32) -> Vec<i32> {let n c…...
使用Golang实现开发中常用的【并发设计模式】
使用Golang实现开发中常用的【并发设计模式】 设计模式是解决常见问题的模板,可以帮助我们提升思维能力,编写更高效、可维护性更强的代码 屏障模式 未来模式 管道模式 协程池模式 发布订阅模式 下面是使用 Go 语言实现屏障模式、未来模式、管道模式…...
基于Zynq FPGA对雷龙SD NAND的性能测试评估
文章目录 一、SD NAND特征1.1 SD卡简介1.2 SD卡Block图 二、SD卡样片三、Zynq测试平台搭建3.1 测试流程3.2 SOC搭建 四、软件搭建五、测试结果六、总结 一、SD NAND特征 1.1 SD卡简介 雷龙的SD NAND系列有多种型号,本次测试使用的是CSNP4GCR01-AMW和CSNP32GCR01-A…...
4.WebSocket 配置与Nginx 的完美结合
序言 在现代 web 应用中,WebSocket 作为一种全双工通信协议,为实时数据传输提供了强大的支持。若要确保 WebSocket 在生产环境中的稳定性和性能,使用 Nginx 作为反向代理服务器是一个明智的选择。本篇文章将带你了解如何在 Nginx 中配置 Web…...
Docker:镜像构建 DockerFile
Docker:镜像构建 DockerFile 镜像构建docker build DockerfileFROMCOPYENVWORKDIRADDRUNCMDENTRYPOINTUSERARGVOLUME 镜像构建 在Docker官方提供的镜像中,大部分都是基础镜像,他们只提供某个简单的功能,如果想要一个功能更加丰富…...
浮动路由:实现出口线路的负载均衡冗余备份。
浮动路由 Tip:浮动路由指在多条默认路由基础上加入优先级参数,实现出口线路冗余备份。 ip routing-table //查看路由表命令 路由优先级参数:越小越优 本次实验测试两条默认路由,其中一条默认路由添加优先级参数,设置…...
二叉树的遍历和线索二叉树
二叉树遍历 二叉树结点的定义 typedef struct BiNode{Elemtype data;struct BiNode* lchild, *rchild; }BiNode, *BiTree; 先序 递归算法 void PreOrder1(BiTree T){if(T!NULL){visit(T);PreOrder(T->lchild);PreOrder(T->rchild);} } 非递归算法(栈实现…...
SpringBoot3 集成Junit4
目录 1. 确保项目中包含JUnit 4依赖添加JUnit 4依赖 2. 配置Spring Boot使用JUnit 4在测试类中使用RunWith注解 3. 编写测试代码4、总结 【扩展】RunWith(SpringRunner.class) 中SpringRunner的作用1. **加载 Spring 应用上下文(ApplicationContext)**2.…...
Scala的set的添加删减和查询
添加:最好用于不可变数组,因为它会产生新数组,而不是在原数组上进行修改。 在尾部添加元素 可变数组 删减:按元素值删除元素 - 查询:查询元素是否存在.contains package Test //Set //特点:元素是唯…...
基于微信小程序的移动学习平台的设计与实现+ssm(lw+演示+源码+运行)
摘 要 由于APP软件在开发以及运营上面所需成本较高,而用户手机需要安装各种APP软件,因此占用用户过多的手机存储空间,导致用户手机运行缓慢,体验度比较差,进而导致用户会卸载非必要的APP,倒逼管理者必须改…...
【spark面试题】RDD和DataFrame以及DataSet有什么异同
RDD(Resilient Distributed Dataset): 概念:可理解为分布式的列表。它的每个元素代表数据的一行,具有支持泛型这一显著特点。这种泛型支持让开发人员能够处理各种类型的数据,具有很强的灵活性。例如&#…...
[Python]关于Tensorflow+Keras+h5py+numpy一些骚操作备忘
起因:要在Anaconda使用Tensorflow和Keras框架 这里提前小结一下: 1,一定要注意Python、Tensorflow、Keras不同版本的对应关系。 2,交叉用conda install 和pip install安装依赖库可能容易出现问题,在Anaconda虚拟环境…...
深度学习:Transformer 详解
Transformer 详解 对于Transformer模型的详细解释,可以更深入地探讨其各个组成部分、工作原理、以及在自然语言处理任务中的应用方法。以下是对Transformer模型的一个更全面和详细的解释,包括其架构细节和关键技术: 1. 基本架构 Transform…...
jmeter 性能测试步骤是什么?
JMeter是一款流行的开源性能测试工具,用于测试各种服务器和网络应用的性能。在进行JMeter性能测试时,通常需要遵循以下步骤: 确定测试目标:首先,明确性能测试的目标。这可以是测试一个网站的负载能力、测试一个API的响…...
前端入门一之JS最基础、最基础语法
前言 JS是前端三件套之一,也是核心,本人将会更新JS基础、JS对象、DOM、BOM、ES6等知识点;这篇文章是本人大一学习前端的笔记;欢迎点赞 收藏 关注,本人将会持续更新。 文章目录 初体验输入输出语句变量和常量常量变量…...
解决Swp交换空间被占满问题
解决ubuntu交换空间被占满问题 step1: cat /proc/sys/vm/swappiness 60 step2: sudo sysctl vm.swappiness10 #临时修改 step3: sudo sh -c “echo “vm.swappiness10” >> /etc/sysctl.conf” step4: sysctl -p #生效...
草地景观中的土地覆被变化:将增强型大地遥感卫星数据组成、LandTrendr 和谷歌地球引擎中的机器学习分类与 MLP-ANN 场景预测相结合
目录 简介 方法 结论 代码1:影像集合 代码2: 随机森林和svm分类 结果 简介 了解草原生境在空间和时间上的动态对于评估保护措施的有效性和制定可持续管理方法至关重要,特别是在自然 2000 网络和欧洲生物多样性战略范围内。 根据遥感数据绘制的土地覆盖图对于了解植被…...
【c++语言程序设计】字符串与浅层复制(深拷贝与浅拷贝)
字符串常量是用一对双引号括起来的字符序列,例如,"abcd" " China"" This is a string." 都是字符串常量。它在内存中的存放形式是,按串中字符的排列次序顺序存放,每个字符占1字节,并在末…...
《TCP/IP网络编程》学习笔记 | Chapter 4:基于TCP的服务器端/客户端(1)
《TCP/IP网络编程》学习笔记 | Chapter 4:基于TCP的服务器端/客户端(1) 《TCP/IP网络编程》学习笔记 | Chapter 4:基于TCP的服务器端/客户端(1)理解TCP和UDPTCP/IP协议栈TCP/IP协议的诞生背景链路层网络层T…...
从零到一:彻底搞懂Anaconda,打造完美的Python开发环境
别再为Python环境搞得焦头烂额了,这篇教程带你一次性解决所有烦恼。 作为Python开发者,你是否曾经遇到过这样的场景:项目A需要Python 3.6和旧版本的TensorFlow,而项目B却要求Python 3.12和最新的PyTorch。如果只在系统里装一个Pyt…...
OPC UA Web访问避坑指南:如何选择RESTful、WebSocket还是GraphQL?
OPC UA Web访问技术选型实战:RESTful、WebSocket与GraphQL深度对比 工业物联网领域的技术架构师们经常面临一个关键决策:如何为OPC UA服务器选择最合适的Web访问方式?这个问题看似简单,却直接影响着系统性能、开发效率和长期维护成…...
纯本地运行!LiuJuan Z-Image Generator隐私安全,生成高质量图片
纯本地运行!LiuJuan Z-Image Generator隐私安全,生成高质量图片 想找一个既保护隐私,又能稳定生成高质量图片的AI工具吗?今天介绍的LiuJuan Z-Image Generator,可能就是你的理想选择。它最大的特点,就是“…...
基于IGH_Master的EtherCAT主站配置与伺服电机/变频器驱动实战指南
1. IGH_Master与EtherCAT基础入门 第一次接触EtherCAT时,我被它的实时性能震惊了——微秒级的响应速度,完全颠覆了我对工业总线的认知。IGH_Master作为开源EtherCAT主站实现,就像是给开发者打开了一扇通往工业自动化的大门。这里我分享下自己…...
wangEditor 5移动端兼容性深度解析:终极跨平台富文本编辑实战指南
wangEditor 5移动端兼容性深度解析:终极跨平台富文本编辑实战指南 【免费下载链接】wangEditor wangEditor —— 开源 Web 富文本编辑器 项目地址: https://gitcode.com/gh_mirrors/wa/wangEditor 在移动优先的时代,富文本编辑器的移动端兼容性已…...
本地部署 LookScanned:轻松将 PDF 转为逼真扫描件,结合内网穿透实现远程访问
前言 本文主要介绍了 LookScanned 这款工具的部署与使用方法。LookScanned 可将普通电子 PDF 转换为高度逼真的纸质扫描件效果,全程本地处理保障隐私,操作简单且无需打印扫描的物理步骤。 文中详细讲解了在极空间通过 Docker 部署 LookScanned 的流程&…...
PHP反序列化实战:手把手教你绕过CTF题中的字符检查与属性保护
PHP反序列化漏洞实战:从CTF解题到真实场景防御 在网络安全竞赛中,PHP反序列化漏洞一直是高频考点。这类漏洞不仅存在于CTF比赛中,也广泛存在于真实世界的Web应用中。本文将从一个典型CTF题目入手,深入剖析PHP反序列化的攻击手法与…...
告别拼接!深入对比鸿蒙与Android的multipart请求封装差异
鸿蒙与Android的multipart请求封装差异:从手动拼接到底层优化 在移动应用开发中,文件上传是一个常见但容易出错的场景。当我们需要同时上传文本和二进制数据时,multipart/form-data协议就成为了标准解决方案。然而,不同平台对这一…...
救命!2026 转行网络安全值不值?薪资 + 工作 + 前景一篇讲透,不踩坑!
网络安全赛道 1、薪资情况 薪资影响因素 2、工作安排与内容 (1) 工作时间(2) 工作内容 3、网络安全前景展望4、如何提升竞争力5、职业技能总结6、学习资源分享 如果你计划在2025年转行到网络安全领域,以下是一些建议,可以帮助你顺利过渡并打下坚实的…...
从提示词到成图:雯雯的后宫-造相Z-Image-瑜伽女孩真实案例分享(含新月式示例)
从提示词到成图:雯雯的后宫-造相Z-Image-瑜伽女孩真实案例分享(含新月式示例) 想用AI生成一张完美的瑜伽女孩图片,却总是被“AI手”、“奇怪姿势”和“塑料感”劝退?别急,今天我们就来手把手拆解一个真实案…...
