问题描述:

现在有个需求,现有一个列表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. Go语言核心36讲(Go语言实战与应用八)--学习笔记

    30 | 原子操作(下) 我们接着上一篇文章的内容继续聊,上一篇我们提到了,sync/atomic包中的函数可以做的原子操作有:加法(add).比较并交换(compare and swap,简称 CA ...

  2. Node.js实现前后端交换——用户登陆

    最近学习了一点Node.js的后端知识,于是作为一个学习前端方向的我开始了解后端,话不多说,开始介绍.首先,如果你想要更好的理解这篇博客,你需要具备html,css,javascript和Node.j ...

  3. [bzoj5340]假面

    修改:维护g[i][j]表示第i个数为j的概率,从前往后转移 转移方程:g[id][i]=g[id][i-1]*p+g[id][i]*(1-p),初始g[i][a[i]]=1 询问:对于每一个人i,输 ...

  4. form-create 3.0 版本发布,好用的Vue3版本动态表单生成组件

    form-create 是一个可以通过 JSON 生成具有动态渲染.数据收集.验证和提交功能的表单生成组件.支持2个UI框架,并且支持生成任何 Vue 组件.内置20种常用表单组件和自定义组件,再复杂 ...

  5. 【IDEA】字体大小和类型

    字体大小和类型 2020-09-08  09:06:21  by冲冲 1.工具界面的字体 2.代码的字体 注意:如果已经设置颜色主题,则还需要设置颜色主题的字体,才能生效.

  6. CSS Web Fonts 网络字体

    Fonts 1. CSS font-family 在 CSS 中,可以使用 font-family 属性来指定字体,浏览器渲染文字时候会根据这个属性应用于元素.如果没有指定这个属性或者指定的字体不存在 ...

  7. 使用微软RPA工具 Power Automate自动完成重复性工作

    介绍 最近发现了win11自带了一个有趣的功能,可以自动去执行一些流程的工作.恰好目前每天早上都需要去提醒同事填写日计划,刚好可以试用下. 这是官网上对此功能的介绍 可以看到,对于win11我们是可以 ...

  8. C++ 编译错误记录

    C++ _ZSt28__throw_bad_array_new_lengthv1 编译错误 出现场景:类似代码 vector<vector<int>> grid = {{1, ...

  9. Codeforces 1383F - Special Edges(状态压缩+最大流)

    Codeforces 题目传送门 & 洛谷题目传送门 首先暴力显然是不行的,如果你暴力最大流过了我请你吃糖 注意到本题的 \(k\) 很小,考虑以此为突破口解题.根据最大流等于最小割定理,点 ...

  10. find命令常见用法

    1. find linux中,find命令一般用来按特定条件查找文件,生产环境中也常用其来过滤文件 名称 find - 搜索目录层次结构中的文件 格式 find [目录] {[选项] [参数]}... ...