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…...
synchronized 学习
学习源: https://www.bilibili.com/video/BV1aJ411V763?spm_id_from333.788.videopod.episodes&vd_source32e1c41a9370911ab06d12fbc36c4ebc 1.应用场景 不超卖,也要考虑性能问题(场景) 2.常见面试问题: sync出…...
精益数据分析(97/126):邮件营销与用户参与度的关键指标优化指南
精益数据分析(97/126):邮件营销与用户参与度的关键指标优化指南 在数字化营销时代,邮件列表效度、用户参与度和网站性能等指标往往决定着创业公司的增长成败。今天,我们将深入解析邮件打开率、网站可用性、页面参与时…...

深入浅出深度学习基础:从感知机到全连接神经网络的核心原理与应用
文章目录 前言一、感知机 (Perceptron)1.1 基础介绍1.1.1 感知机是什么?1.1.2 感知机的工作原理 1.2 感知机的简单应用:基本逻辑门1.2.1 逻辑与 (Logic AND)1.2.2 逻辑或 (Logic OR)1.2.3 逻辑与非 (Logic NAND) 1.3 感知机的实现1.3.1 简单实现 (基于阈…...

Windows安装Miniconda
一、下载 https://www.anaconda.com/download/success 二、安装 三、配置镜像源 Anaconda/Miniconda pip 配置清华镜像源_anaconda配置清华源-CSDN博客 四、常用操作命令 Anaconda/Miniconda 基本操作命令_miniconda创建环境命令-CSDN博客...
Web中间件--tomcat学习
Web中间件–tomcat Java虚拟机详解 什么是JAVA虚拟机 Java虚拟机是一个抽象的计算机,它可以执行Java字节码。Java虚拟机是Java平台的一部分,Java平台由Java语言、Java API和Java虚拟机组成。Java虚拟机的主要作用是将Java字节码转换为机器代码&#x…...

(一)单例模式
一、前言 单例模式属于六大创建型模式,即在软件设计过程中,主要关注创建对象的结果,并不关心创建对象的过程及细节。创建型设计模式将类对象的实例化过程进行抽象化接口设计,从而隐藏了类对象的实例是如何被创建的,封装了软件系统使用的具体对象类型。 六大创建型模式包括…...
第7篇:中间件全链路监控与 SQL 性能分析实践
7.1 章节导读 在构建数据库中间件的过程中,可观测性 和 性能分析 是保障系统稳定性与可维护性的核心能力。 特别是在复杂分布式场景中,必须做到: 🔍 追踪每一条 SQL 的生命周期(从入口到数据库执行)&#…...
掌握 HTTP 请求:理解 cURL GET 语法
cURL 是一个强大的命令行工具,用于发送 HTTP 请求和与 Web 服务器交互。在 Web 开发和测试中,cURL 经常用于发送 GET 请求来获取服务器资源。本文将详细介绍 cURL GET 请求的语法和使用方法。 一、cURL 基本概念 cURL 是 "Client URL" 的缩写…...

华为OD机试-最短木板长度-二分法(A卷,100分)
此题是一个最大化最小值的典型例题, 因为搜索范围是有界的,上界最大木板长度补充的全部木料长度,下界最小木板长度; 即left0,right10^6; 我们可以设置一个候选值x(mid),将木板的长度全部都补充到x,如果成功…...
Python竞赛环境搭建全攻略
Python环境搭建竞赛技术文章大纲 竞赛背景与意义 竞赛的目的与价值Python在竞赛中的应用场景环境搭建对竞赛效率的影响 竞赛环境需求分析 常见竞赛类型(算法、数据分析、机器学习等)不同竞赛对Python版本及库的要求硬件与操作系统的兼容性问题 Pyth…...