ant-design / pro-components

🏆 Use Ant Design like a Pro!
https://pro-components.antdigital.dev
MIT License
4.3k stars 1.36k forks source link

🐛[BUG] ModalForm 子元素的`transform`函数会在初始化时触发且忽视`convertValue` #8452

Open myuanz opened 5 months ago

myuanz commented 5 months ago

🐛 bug 描述

根据文档:

transform 发生在提交的时候,一般来说都是吐给后端的存在数据库里的数据。

但是我注意到当我给出initialValues的时候,transform就会在初始化的时候触发,而且会无视convertValue返回的东西

📷 复现步骤

https://codesandbox.io/p/sandbox/modal-biao-dan-forked-dx2fss

打开 Console -> 点击新建表单 -> 观察输出 图片

🏞 期望结果

transform只在提交时运行,或者至少transform会接到convertValue的返回值,而不是只用initialValues

💻 复现代码

https://codesandbox.io/p/sandbox/modal-biao-dan-forked-dx2fss

© 版本信息

fnoopv commented 5 months ago

问题是啥?这个逻辑影响了什么?完全没看明白。 而且感觉这个逻辑没问题啊,数据流是这样的 initValues-convertValue-组件内部-transform-提交的值, 感觉这个数据流是合理的。

myuanz commented 5 months ago

这里的问题是

  1. 没有提交就触发transform函数
  2. 上一步的transform函数的入参不是convertValue的返回
fnoopv commented 5 months ago

这里的问题是

  1. 没有提交就触发transform函数
  2. 上一步的transform函数的入参不是convertValue的返回

纯粹讨论逻辑没意义, 你应该说清楚目前这个逻辑对你的业务产生了什么影响?不符合你这个逻辑会产生什么预期之外的结果?根据现象去讨论问题才有意义。

myuanz commented 5 months ago

当然是因为对业务产生了影响我才注意到这个,但是已经偏离主题太远了。而且文档描述跟逻辑不符本身就是问题,如果文档就是说transform会在初始化时调用一次而且参数是原始值,我只会觉得设计不合理,不会开这个issue。


考虑这样一种情况:我需要填入若干个基因,后端约定用|分割基因,比如"FOXP2|GNB4"这样是两个基因。基因很多又容易写错大小写,于是我用ProFormSelect提供了下拉框,其值是string[]的,因此传入后端时需要transform: v => v.join('|'),编辑时需要从后端convertValue: v => v.split('|')

当我打算编辑时,给出了initialValues期待得到预填充,但初始化时transform就会被调用,其输入还是未经过convertValue的数据库原始表示,是个 string,于是就有了value.join is not a function

  1. 如果transform输入是convertValue过的,那这一次多调用无所谓,反正这是个纯函数
  2. 如果按照文档,transform发生在提交时,那也无所谓,因为提交时transform的输入就是数组

有一些规避方式,我已实施,不必多谈

fnoopv commented 5 months ago

这样看确实存在问题,初始化时调用transform这个操作没啥影响,主要是初始化调用transform时传给transform的指不符合组件值的格式

markwei19960204 commented 2 months ago

当然是因为对业务产生了影响我才注意到这个,但是已经偏离主题太远了。而且文档描述跟逻辑不符本身就是问题,如果文档就是说transform会在初始化时调用一次而且参数是原始值,我只会觉得设计不合理,不会开这个issue。

考虑这样一种情况:我需要填入若干个基因,后端约定用|分割基因,比如"FOXP2|GNB4"这样是两个基因。基因很多又容易写错大小写,于是我用ProFormSelect提供了下拉框,其值是string[]的,因此传入后端时需要transform: v => v.join('|'),编辑时需要从后端convertValue: v => v.split('|')

当我打算编辑时,给出了initialValues期待得到预填充,但初始化时transform就会被调用,其输入还是未经过convertValue的数据库原始表示,是个 string,于是就有了value.join is not a function

  1. 如果transform输入是convertValue过的,那这一次多调用无所谓,反正这是个纯函数
  2. 如果按照文档,transform发生在提交时,那也无所谓,因为提交时transform的输入就是数组

有一些规避方式,我已实施,不必多谈

你好 请问你的规避方式是什么 我也遇到了这个问题,initialValues初始化设置值后,通过convertValue转化成表单希望的值,然后表单提交时,transform不生效了呢

myuanz commented 2 months ago

当然是因为对业务产生了影响我才注意到这个,但是已经偏离主题太远了。而且文档描述跟逻辑不符本身就是问题,如果文档就是说transform会在初始化时调用一次而且参数是原始值,我只会觉得设计不合理,不会开这个issue。 考虑这样一种情况:我需要填入若干个基因,后端约定用|分割基因,比如"FOXP2|GNB4"这样是两个基因。基因很多又容易写错大小写,于是我用ProFormSelect提供了下拉框,其值是string[]的,因此传入后端时需要transform: v => v.join('|'),编辑时需要从后端convertValue: v => v.split('|')。 当我打算编辑时,给出了initialValues期待得到预填充,但初始化时transform就会被调用,其输入还是未经过convertValue的数据库原始表示,是个 string,于是就有了value.join is not a function

  1. 如果transform输入是convertValue过的,那这一次多调用无所谓,反正这是个纯函数
  2. 如果按照文档,transform发生在提交时,那也无所谓,因为提交时transform的输入就是数组

有一些规避方式,我已实施,不必多谈

你好 请问你的规避方式是什么 我也遇到了这个问题,initialValues初始化设置值后,通过convertValue转化成表单希望的值,然后表单提交时,transform不生效了呢

我的问题是transform在开始就初始化, 你的问题是transform在提交时不生效, 这两个不一样, 我没有遇到你的问题. 我的问题解决方案是在传入组件之前在其他地方转换数据