问题描述:

现在有个需求,现有一个列表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组件不更新问题的更多相关文章

  1. 深入理解React:diff 算法

    目录 序言 React 的核心思想 传统 diff 算法 React diff 两个假设 三个策略 diff 具体优化 tree diff component diff element diff 小结 ...

  2. React的Diff算法

    使用React或者RN开发APP如果不知道Diff算法的话简直是说不过去啊.毕竟"知其然,知其所以然"这句老话从远古喊到现代了. 以下内容基本是官网文章的一个总结.压缩.这次要谦虚 ...

  3. 个人对于React的Diff算法的一点疑问(待更新)

    本人对于Diff算法也并未做深入研究,只是大概的看过一些博文了解了些原理,但依然有了如下疑问 : 对于vdom所表示的对象中,若在该oldObj和newObj之间,发现一个元素节点所表示的子对象不见了 ...

  4. React的diff算法(译文)

    前言  此篇文章主要是因为在看Virtual DOM(虚拟DOM)的时候看到的主要讲的是实现Virtual Dom 的diff算法,原文地址:https://calendar.perfplanet.c ...

  5. react中虚拟dom的diff算法

    .state 数据 .jsx模板 .生成虚拟dom(虚拟DOM就是一个js对象,用它来描述真实DOM) ['div', {id:'abc'}, ['span', {}, 'hello world']] ...

  6. React——diff算法

    react的diff算法基于两个假设: 1.不同类型的元素会产生不同的树 2.通过设置key,开发者能够提示那些子组件是稳定的 diff算法 当比较两个树时,react首先会比较两个根节点,接下来具体 ...

  7. react性能调谐与diff算法

    一个页面其实就相当于是一颗dom树,里面有很多它的子节点,然后你每次去操作一个事件,它都会生成一个虚拟dom,它会跟上一个虚拟dom进行比对,这里运用的算法叫做diff算法,当它找到需要改变的组件的时 ...

  8. diff算法

    diff算法的作用计算出Virtual DOM中真正变化的部分,并只针对该部分进行原生DOM操作,而非重新渲染整个页面. 传统diff算法 通过循环递归对节点进行依次对比,算法复杂度达到 O(n^3) ...

  9. 虚拟dom?diff算法?key?Vue原理的核心三问?打包教你搞定。

    为什么需要虚拟DOM 先介绍浏览器加载一个HTML文件需要做哪些事,帮助我们理解为什么我们需要虚拟DOM.webkit引擎的处理流程,如下图所示: 所有浏览器的引擎工作流程都差不多,如上图大致分5步: ...

随机推荐

  1. Windows11下的快捷键(win10通用,部分win11独有的不通用)

    给大家介绍一下win11下我常用的几个快捷键,在微软官方的文档里面都可以查到,官网链接 https://support.microsoft.com/zh-cn/windows/windows-%E7% ...

  2. dos的基本命令

    打开cmd的方式 开始+系统+命令提示符 Win键+R 输入cmd打开控制台(推荐使用) 在任意的文件夹下面,按住shift键+鼠标右键点击,在此处打开命令行窗口 资源管理器的地址栏前面加上cmd + ...

  3. Java 如何对文件进行多个Object对象流的读写操作

    思路:把已经序列化的对象存入容器(如LinkedList<?>)中,然后用ObjectInputStream和ObjectOutputStream对这个实例化的LinkedList< ...

  4. [gym102832J]Abstract Painting

    考虑每一个圆即对应于区间$[x_{i}-r_{i},x_{i}+r_{i}]$,可以看作对于每一个区间,要求所有右端点严格比其小的区间不严格包含左端点 用$f_{i}$表示仅考虑右端点不超过$i$的区 ...

  5. [atAGC007E]Shik and Travel

    二分枚举答案,判定答案是否合法 贪心:每一个叶子只能经过一遍,因此叶子的顺序一定是一个dfs序,即走完一棵子树中的所有叶子才会到子树外 根据这个贪心可以dp,设$f[k][l][r]$表示仅考虑$k$ ...

  6. N皇后问题解法

    // // Created by Administrator on 2021/8/5. // #ifndef C__TEST01_NQUEENS_HPP #define C__TEST01_NQUEE ...

  7. [Noip 2012]同余方程(线性同余方程)

    我们先放题面-- RT就是求一个线性同余方程ax≡1(mod b)的最小正整数解 我们可以将这个同于方程转换成这个方程比较好理解 ax=1+bn(n为整数 我们再进行一个移项变为ax-bn=1 我们设 ...

  8. 毕业设计之zabbix=[web检测

    网站对一个公司来说非常重要,里边包含了公司的业务,介绍和订单等相关信息,网站的宕掉了对公司的影响非常重大,所以要很好的对网站的页面进行监控 创建web场景 各部分介绍: Name:唯一的scenari ...

  9. 【R】如何去掉数据框中包含非数值的行?

    目录 1. 去掉指定列中包含NA/Inf/NaN的行 2. 去掉指定列中包含其他乱七八糟字符串的行 3. 去掉整个数据框中包含非数值的行 只包含NA.NaN和Inf的情况 针对其他字符情况 4. 总结 ...

  10. JavaScript中var与let的异同点

    var是JavaScript刚出现时就存在的变量声明关键字,而let作为ES6才出现的变量声明关键字,无疑两者之间存在着很大的区别.那么具体有哪些区别呢? 1.作用域表现形式不同,var是函数作用域, ...