ant-design / compatible

https://compatible.now.sh
MIT License
89 stars 23 forks source link

@ant-design/compatible中Form包裹下,Radio.Group 配置options获取不到value,配置children正常 #70

Closed feibi closed 4 years ago

feibi commented 4 years ago

Reproduction link

Edit on CodeSandbox

Steps to reproduce

  1. Form从@ant-design/compatible导入
  2. Radio从antd导入
  3. radio1不能赋值,radio2可以赋值
    
    import React from "react";
    import ReactDOM from "react-dom";
    import { Form } from "@ant-design/compatible";
    import { Button, Radio } from "antd";
    import "@ant-design/compatible/assets/index.css";

class MyForm extends React.Component { render() { const { form } = this.props; return ( <Form onSubmit={e => { e.preventDefault(); form.validateFieldsAndScroll((err, values) => { if (!err) { console.log("values", values); } }); }}

{form.getFieldDecorator("radio1", { initialValue: "1" })( )} {form.getFieldDecorator("radio2", { initialValue: "1" })( radio2 item1 radio2 item2 )} ); } }

const AForm = Form.create()(MyForm); ReactDOM.render(, document.getElementById("container"));



### What is expected?
radio1能正确获取到值

### What is actually happening?
1. 初始化时radio1有值,但没有选中。
2. 任意改变某个控件,radio1的值都为undefined

| Environment | Info |
|---|---|
| antd | 4.5.1 |
| React | 16.13.1 |
| System | window 10 |
| Browser | chrome 84 |

<!-- generated by ant-design-issue-helper. DO NOT REMOVE -->
afc163 commented 4 years ago

https://codesandbox.io/s/antd-radio-group-shk2b?file=/index.js

抱歉,我贴错链接了:https://codesandbox.io/s/antd-radio-group-uwt6g?file=/index.js

feibi commented 4 years ago

https://codesandbox.io/s/antd-radio-group-shk2b?file=/index.js

为什么给关闭了,给下原因呢

afc163 commented 4 years ago

请看一下正确的写法:https://codesandbox.io/s/antd-radio-group-uwt6g?file=/index.js

feibi commented 4 years ago

请看一下正确的写法:https://codesandbox.io/s/antd-radio-group-uwt6g?file=/index.js

我的例子initialValue写的不对,那不是重点。。重点是提交时console.log打印的radio1始终为undefined

afc163 commented 4 years ago

确实诡异,测试 antd v4 的 Form 是好的 https://codesandbox.io/s/antd-radio-group-d6o4l?file=/index.js

antd v3 也是好的:https://codesandbox.io/s/antd-radio-group-dc0k1?file=/index.js

应该是 compatible 这个包的问题。

shaodahong commented 4 years ago

Cause by https://github.com/ant-design/ant-design/compare/4.4.0...4.4.1

afc163 commented 4 years ago

https://github.com/ant-design/ant-design/pull/25328

shaodahong commented 4 years ago

看了下确实是加了 Ref 导致的,需要判断下

xyy94813 commented 4 years ago

如果 Radio.Group 外面包一层 class ,form 又能能够正常赋值。

可查看基于 @feibi 的示例做的变更版本: example

shaodahong commented 4 years ago

如果 Radio.Group 外面包一层 class ,form 又能能够正常赋值。

可查看基于 @feibi 的示例做的变更版本: example

@xyy94813

嗯,根本原因其实在于错误的使用了 Ref

老得 Form item 会 inject Ref(什么原因我不清楚), 而 V4 Antd 的 Radio.Group 会对 options 是 Array 的情况下实行

const radioGroupChildren = options.map( option => <Radio ref={ref} /> )

代码见 https://github.com/ant-design/ant-design/blob/2b71085e68ae8529f7463f08ff6f14f3e80abc42/components/radio/group.tsx#L49

至于你说的变更例子版本包了一层为什么能用,是因为你没有处理 ref,不信你 forwardRef 一下试试

ForwardRef Example

xyy94813 commented 4 years ago

https://github.com/ant-design/ant-design/blob/2b71085e68ae8529f7463f08ff6f14f3e80abc42/components/radio/group.tsx#L49

这也是我存在疑惑的地方, 为什 forwardRef 会传递给所有的 Radio 组件。 这个 ref 的值难道不是一直最终指向最后一个 Radio (RC-CheckBox)组件?

shaodahong commented 4 years ago

心智上来说一个 Ref 不应该多次使用,但是多次使用导致 v3 Form 的怪异问题,属于边界情况,处理下就行

xyy94813 commented 4 years ago

按我目前的理解,这个问题是由于 Radio.Group 错误使用 ref 的方式导致的。 应该在 Radio.Group 的层面去解决这个问题。

不管是否与 compatible 结合使用,v4 中 Radio.Group 的处理 Ref 的方式都是存在疑问的。

shaodahong commented 4 years ago

@zombieJ 帮忙看下这个

zombieJ commented 4 years ago

这个 group 的 ref fix 有点问题,它本身不需要支持 ref: https://github.com/ant-design/ant-design/pull/25328#issuecomment-653604137

zombieJ commented 4 years ago

https://github.com/ant-design/ant-design/pull/26418

shaodahong commented 4 years ago

Closed by https://github.com/ant-design/ant-design/pull/26418