react的diff算法与antd中switch组件不更新问题
问题描述:
现在有个需求,现有一个列表table,里面的数据有启用的也有关闭的,switch组件会根据数据状态展示,同时进行排序,启用数据在前面,未启用的在后面.如图

然后现在需要操作,假如我将第四条数据'的撒管道施工'进行启用,调用启用接口,改变switch组件状态,并重新调用列表查询接口,理想效果,列表数据按启用排序,前三条应该是启用,其他情况是未启用.可实际结果如图

所操作的数据状态确实对了,排序也ok的,但是"第四条数据的switch组件状态没有更新",刷新页面之后,组件更改了.

也就是结果是,switch正确切换了,但是第二次回显还是保留了回显前的状态.代码
代码如下:
{
title: '是否启用',
dataIndex: 'whetherUseing',
key: 'whetherUseing',
// width: 150,
render: (text, record, index) => {
if (text === 1) {
return (
<div
id={`${record.id}${index}${text}`}
// key={`${record.id}${index}${text}`}
>
<Switch
defaultChecked={true}
disabled={!access_enable}
onChange={(value) => startOrEnd(value, record)}
/>
</div>
);
} else {
return (
<p
id={`${record.id}${index}${text}`}
// key={`${record.id}${index}${text}`}
>
<Switch
defaultChecked={false}
disabled={!access_enable}
onChange={(value) => startOrEnd(value, record)}
/>
</p>
);
}
},
},
产生现象的原因:
主要是react的diff算法导致的.diff算法在以下三种情况时会重新构建一个新的DOM树.
(1)当dom的种类发生变化时,比如div变成了p标签
(2)当dom的结构发生变化时,比如由原来的父子结构变成了兄弟结构
(3)当dom的key发生变化时,你可以为dom元素加上key属性,当(1)和(2)不满足时,可以属性发生变化也会导致重新构建dom树
那switch组件这边发生了什么呢?
启用前:switch组件的父元素是一个p标签,打开tab第五栏的开关之后,开关变成了打开状态.接下来就是问题所在,当重新调接口后,该数据确实变成了启用状态,排在了前面(正确),但是,table第四栏的数据是关闭状态,所以逻辑上仍然走else,所以swtich的父元素dom种类没变,dom结构也没变仍是p标签.所以swtich标签以及p标签并不会更新.所以保持了打开状态.其结果就是,明明数据变成了关闭,可switch标签仍是打开状态.简单来说就是.
主体:table的第四栏的swtich(并非是某条数据) 过程:关闭-----(手动打开,此处此时的数据状态仍为关闭,但是swtich的checked属性变成了true)----->>>打开---------(调用接口,数据更新,第四栏的数据更新了,变成了别的数据,而这条数据仍是关闭.switch开关保持原样,checked属性仍为true)------>>打开(更新了,但没完全更新)
解决方案:
给switch标签加上key属性,既然你数据变了,而我也希望你switch也跟着边,那我就把你的key和你的相关数据绑定.根据diff算法特性,只要你key变了,那就会重新渲染
代码:
{
title: '是否启用',
dataIndex: 'whetherUseing',
key: 'whetherUseing',
// width: 150,
render: (text, record, index) => {
if (text === 1) {
return (
<div
id={`${record.id}${index}${text}`}
key={`${record.id}${index}${text}`}
>
<Switch
defaultChecked={true}
disabled={!access_enable}
onChange={(value) => startOrEnd(value, record)}
/>
</div>
);
} else {
return (
<p
id={`${record.id}${index}${text}`}
key={`${record.id}${index}${text}`}
>
<Switch
defaultChecked={false}
disabled={!access_enable}
onChange={(value) => startOrEnd(value, record)}
/>
</p>
);
}
},
},
主体:table的第四栏的swtich(并非是某条数据) 过程:关闭-----(手动打开,此处此时的数据状态仍为关闭,但是swtich的checked属性变成了true)----->>>打开---------(调用接口,数据更新,第四栏的数据更新了,变成了别的数据,而这条数据仍是关闭.在结构和标签类型都不变的情况下,key发生了变化,重新构建渲染)------>>关闭(重新构建一个p标签,并获得 defaultChecked={false} )
react的diff算法与antd中switch组件不更新问题的更多相关文章
- 深入理解React:diff 算法
目录 序言 React 的核心思想 传统 diff 算法 React diff 两个假设 三个策略 diff 具体优化 tree diff component diff element diff 小结 ...
- React的Diff算法
使用React或者RN开发APP如果不知道Diff算法的话简直是说不过去啊.毕竟"知其然,知其所以然"这句老话从远古喊到现代了. 以下内容基本是官网文章的一个总结.压缩.这次要谦虚 ...
- 个人对于React的Diff算法的一点疑问(待更新)
本人对于Diff算法也并未做深入研究,只是大概的看过一些博文了解了些原理,但依然有了如下疑问 : 对于vdom所表示的对象中,若在该oldObj和newObj之间,发现一个元素节点所表示的子对象不见了 ...
- React的diff算法(译文)
前言 此篇文章主要是因为在看Virtual DOM(虚拟DOM)的时候看到的主要讲的是实现Virtual Dom 的diff算法,原文地址:https://calendar.perfplanet.c ...
- react中虚拟dom的diff算法
.state 数据 .jsx模板 .生成虚拟dom(虚拟DOM就是一个js对象,用它来描述真实DOM) ['div', {id:'abc'}, ['span', {}, 'hello world']] ...
- React——diff算法
react的diff算法基于两个假设: 1.不同类型的元素会产生不同的树 2.通过设置key,开发者能够提示那些子组件是稳定的 diff算法 当比较两个树时,react首先会比较两个根节点,接下来具体 ...
- react性能调谐与diff算法
一个页面其实就相当于是一颗dom树,里面有很多它的子节点,然后你每次去操作一个事件,它都会生成一个虚拟dom,它会跟上一个虚拟dom进行比对,这里运用的算法叫做diff算法,当它找到需要改变的组件的时 ...
- diff算法
diff算法的作用计算出Virtual DOM中真正变化的部分,并只针对该部分进行原生DOM操作,而非重新渲染整个页面. 传统diff算法 通过循环递归对节点进行依次对比,算法复杂度达到 O(n^3) ...
- 虚拟dom?diff算法?key?Vue原理的核心三问?打包教你搞定。
为什么需要虚拟DOM 先介绍浏览器加载一个HTML文件需要做哪些事,帮助我们理解为什么我们需要虚拟DOM.webkit引擎的处理流程,如下图所示: 所有浏览器的引擎工作流程都差不多,如上图大致分5步: ...
随机推荐
- python实现圆检测
目录: (一)霍夫圆检测原理 (二)代码实现 (一)霍夫圆检测原理 (二)代码实现 1 #霍夫圆检测 2 import cv2 as cv 3 import numpy as np 4 5 def d ...
- .net工程师学习vue的心路历程(二)
本章主要搞懂在通过vue init webpack projectname 命令创建 vue 项目过程中有个选择.即关于如何选择:runtime+compiler和runtime+only. 现在我通 ...
- 微信公众号生成海报(uniapp)
前言 这几天接到一个需求,要在公众号内生成分享海报.之前有做过H5和小程序的,心想直接复制过来就行了.没想到踩了不少的坑,搞了好几天终于搞好了,特此分享一下,希望能对大家有所帮助. 效果图 代码实现 ...
- [bzoj5416]冒泡排序
结论:一个序列是好序列当且仅当其不存在长度为3的下降子序列 证明:考虑提示,一个长度为3的下降子序列必然会交换三次, 而这三次带来的收益实际上只有2,因此不合法 同时还可以得到:第i个数,要么是前缀最 ...
- [luogu6860]象棋与马
根据扩欧$(a,b)=1$必须要满足,同时,若$a+b$为偶数则格子的"奇偶性"不变,因此$a+b$必须为奇数 反过来,容易证明满足$(a,b)=1$且$a+b$为奇数则一定可行( ...
- 【Tool】IntelliJ IDEA 使用技巧
IntelliJ IDEA 使用技巧 2019-11-06 20:51:43 by冲冲 1.快捷键 Ctrl+w //括出相关范围 Ctrl+shift+f //按照代码段在全局搜索 Ctrl+f ...
- 柯基数据通过Rainbond完成云原生改造,实现离线持续交付客户
1.关于柯基数据 南京柯基数据科技有限公司成立于2015年,提供一站式全生命周期知识图谱构建和运维.智能应用服务,致力于"链接海量数据,从大数据中挖掘智慧".帮助企业运用知识 ...
- Kubernetes-网络
前言 本篇是Kubernetes第十一篇,大家一定要把环境搭建起来,看是解决不了问题的,必须实战,此篇文章概念比较多,后续我会继续出一些网络相关实战以及原理探索篇. Kubernetes系列文章: K ...
- [NOI2020] 超现实树
我们定义链树为:在该树上的任意节点,左右子树大小的最小值小于2. 举个例子: 那么我们思考,链树显然可以在叶子节点任意替换成其他子树. 那么在主链上,我们可以做到生成任意深度大于主链长度的树. 反过来 ...
- [R] venn.diagram保存pdf格式文件?
vennDiagram包中的主函数绘图时,好像不直接支持PDF格式文件: dat = list(a = group_out[[1]][,1],b = group_out[[2]][,1]) names ...