V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
admol
V2EX  ›  前端开发

请教下 ant.design 表单列渲染多个复选框值出现的问题

  •  
  •   admol ·
    admol · 2021-10-14 10:44:37 +08:00 · 903 次点击
    这是一个创建于 1140 天前的主题,其中的信息可能已经有所发展或是发生改变。

    描述信息

    一个支持标签权限设置的列表,使用的是 antd 的 ProTable 、ProColumns 。table 有两个字段使用了 ProColumns 的 render,渲染成一个复选框,表示是否有选中。

    下面是两列中的 render 内容。

    {
          title: formatMessage({id: "authority.role.field.maintenance"}),
          width: 100,
          dataIndex: 'roleTagAcl',
          hideInSearch: true,
          render: (value: number, record) => {
            const checked = ((record.roleTagAcl & 1) === 1);
            console.log("(value & 1) === 1",record.serviceCode,record.roleTagAcl,checked)
            return <Checkbox name="binding"
                             defaultChecked={checked}
                             onChange={(value) => handleBoxChange(value,record)}></Checkbox> ;
          },
    },
    {
          title: formatMessage({id: "authority.role.field.binding"}),
          width: 100,
          dataIndex: 'roleTagAcl',
          hideInSearch: true,
          render: (value: number, record) => {
            const checked = ((record.roleTagAcl & 2) === 2);
            console.log("(value & 2) === 2",record.serviceCode,record.roleTagAcl,checked)
            return <Checkbox name="binding"
                             defaultChecked={checked}
                             onChange={(value) => handleBoxChange(value,record)}></Checkbox> ;
          },
    },
    

    问题描述

    现在有几个问题

    1. 第一次进入到列表的时候,我上面的那一行日志会输出多次( 4 次 5 次都有过),注意我输出了 record.serviceCode,根据 console 日志可以看到输出了几次。 第一次进入列表输出的 console 日志:https://pastebin.com/BH5RTnQT
    2. 进入列表后,输入查询条件( serviceCode ),点击查询。console 输出了所有的记录日志,然后才输出我指定查询条件的日志,且都是多条。 第一次点击查询后的 console 输出日志:https://pastebin.com/igg9VvDk
    3. 我搜索一个存在的标签( serviceCode )后,render 渲染出来的复选框选中结果始终和无搜索条件时的列表中的第一行记录的渲染结果一致。 就算日志输出的 checked 是 false,如果列表中的第一行是选中的,搜索后渲染出来的就是选中。总结就是列表中第一行的复选框是什么状态,搜索一条指定的记录后渲染出来的就是什么状态,搜索结果中的第一行记录不会根据我 render 里面的代码来渲染结果。
    4. 第一次点击查询会先输出整个列表的日志,后面多次点击查询后的 console 输出日志就仅仅有指定搜索条件的多次输出日志了,和第二个问题类似,但是少了列表日志的一部分:https://pastebin.com/SufiMGAk

    总结

    1. 我观察到了无论我后端接口那个字段返回是 null 还是 0 还是其他值,复选框的选中状态都不能正确渲染。
    2. 日志会输出多次,这个我不能理解为什么,不知道为什么要这样渲染,希望大佬能赐教。
    3. 我看到了 react 文档里面的一个副作用,但是还没能怎么看懂,是不是 render 使用的问题?
    4. 项目整体用到的是 react+antd,零零散散刚接触这个不到 2 个月,还不是很懂这个,希望有知道问题的大佬能帮忙解惑下。
    第 1 条附言  ·  2021-10-14 12:29:00 +08:00
    我用官方的一个例子( https://codesandbox.io/s/000vqw38rl?file=/index.js )稍微改造了一下,我改造后的例子( https://codesandbox.io/s/young-wood-y59ev?file=/index.js
    发现改造后的 console 也是输出了多次,不知道为什么。
    3 条回复    2021-10-14 13:30:43 +08:00
    lalalaqwer
        1
    lalalaqwer  
       2021-10-14 12:22:41 +08:00
    1 因为每条数据渲染都会输出日志,所以你可以看到多次日志
    2 查询的时候,可能先触发了一次渲染,所以输出所有日志,然后有结果了再渲染查询的结果,所以后输出指定的日志
    3 系统的优化问题,你渲染的组件存在着复用的情况,所以跟第一条的结果看着是一样的
    4 跟 2 一样的
    以前用过 antd, 那时候没有 Pro-XXX 的,没有代码,以上都是我瞎猜的
    admol
        2
    admol  
    OP
       2021-10-14 12:33:17 +08:00
    @lalalaqwer
    你说的 1 我能理解,但是我查询结果就一条时,也看到了多次日志输出,为什么 render 里面要执行多次呢?对应的日志不应该也只是输出一条吗。
    你说的 2,为什么要先出发一次渲染呢?第三点的复用我也不是很明白,现在我也是在猜,不咋懂。
    大佬再看下我 append 的例子,日志也是多次输出
    lalalaqwer
        3
    lalalaqwer  
       2021-10-14 13:30:43 +08:00   ❤️ 1
    @admol
    看了你贴的例子,我也发现了,初始进去的时候同一条记录会有两次日志输出。想去看看源码,hooks 看得人头大,试着把 antd 降到没有用 hooks 的 3.X 版本后就只有一次渲染了,可以猜这个是组件中用了 hooks 但是有地方没做优化导致的二次渲染。然后为什么要先触发一次渲染也可能是这个问题吧,你查询的时候改变了一些东西,然后在结果出来之前触发了一次渲染
    3 的话你这个因为是 defaultChecked,应该是 antd 的特性,第一次渲染的时候预设的值。后面渲染的时候组件不是整个重新渲染的,只修改了改变的部分数据的渲染,而预设值只是第一次有效
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1034 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 24ms · UTC 22:06 · PVG 06:06 · LAX 14:06 · JFK 17:06
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.