[Field]自定义组件在unmount后,还是校验了 #3962

 

Comments

@cwtuan
 
 

cwtuan commented 15 days ago

Component

Field

Reproduction link

https://riddle.alibaba-inc.com/riddles/27d1ebab

import ReactDOM from 'react-dom';
import React from 'react';
import { Input, Button, Checkbox, Field,Form,Select } from '@alifd/next';

const CheckboxGroup = Checkbox.Group;
const dataSource=[1,2,3];

const MySelect = (props) => {
  return <Select {...props}/>
}


class App extends React.Component {
  
    field = new Field(this, {scrollToFirstError: -10});

    notEmpty(rule, value) {
    if (!value || value.length==0) {
      return Promise.reject("必选");
    } else {
      return Promise.resolve(null);
    }
  }


    render() {
        const init = this.field.init;

        return (<div className="demo">
        <Form field={this.field}>


        <Form.Item>
        <Input
        {...init('input', {
        })} />
        </Form.Item>

        {
          this.field.getValue('input') && 
          <>
         
            <Form.Item>
              <Select
              multiple
              dataSource={dataSource}
              {...init('next_select', {
                  rules: [{validator: this.notEmpty}]
              })} />
            </Form.Item>

              <Form.Item>
              <MySelect
              multiple
              dataSource={dataSource}
              {...init('my_select', {
                  rules: [{validator: this.notEmpty}]
              })} />
            </Form.Item>
          </>
        }

      </Form>
        
            <br/>

            <Button type="primary" onClick={() => {
                this.field.validatePromise().then(({errors, values}) => {
                    console.warn('aaa errors',errors);
                    console.log('aaa values',values)
                });
            }}>validate</Button>
         
        </div>);
    }
}

ReactDOM.render(<App/>, mountNode);

Steps to reproduce

  1. Input输入1,点Validate按钮,next_select、my_select为空,校验不通过 => 符合预期
    image

  2. Input清除,点Validate按钮,next_select、my_select都被Unmount了,不应该校验。
    next_select => 没有校验,符合预期
    my_select => 校验了,不符合预期

image

next_select是fusion原生组件,my_select只是包装成自定义组件(但里面也是Fusion原生组件)

const MySelect = (props) => {
  return <Select {...props}/>
}
 
 
@bindoon
 
Member

bindoon commented 15 days ago • 

edited 

你的组件不支持 ref,需要用 React.forwordRef 包裹下

const MySelect = React.forwordRef((props, ref) => {
  return <Select {...props} ref={ref}/>
})
 
@cwtuan
 
Author

cwtuan commented 15 days ago

那最好在文档描述一下这个问题和解法。

但我觉得这样对使用上很不方便,你们再看看,能否改变实现,不要靠ref

 
 
 
@bindoon bindoon self-assigned this 15 days ago
@bindoon
 
Member

bindoon commented 15 days ago

那最好在文档描述一下这个问题和解法。

但我觉得这样对使用上很不方便,你们再看看,能否改变实现,不要靠ref

  • 文档我加下。
  • 如果你不写ref,我就得包裹一层组件,比较担心性能的问题
 
@cwtuan
 
Author

cwtuan commented 15 days ago • 

edited 

包裹一层组件,比较担心性能的问题 =>

能否在useField的参数,让用户选择是否要包组件,默认可以不开启。
我想大部分场景都不太会有性能问题,使用上会方便很多(不然每次用这个组件,都需要传个ref)

 
@bindoon
 
Member

bindoon commented yesterday • 

edited 

可以业务线自己写 HOC 包裹下组件,不一定要传 Ref,只需要用 HOC 里面用 React.Component 包裹下。

Fusion 的基础组件都是 React.Component ,所以不需要包裹。

包裹方式:

import OldComponent from './xxxx';

export default class NewComponent extends React.Compoent {
     render() {
          return <OldComponent {...this.props} />
     }
}

HOC 方式:

export default function HOC(Component) {
    class NewComponent extends React.Compoent {
         render() {
              return <Component {...this.props} />
         }
    }
    return NewComponent;
}
 
 
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

posted on 2022-07-07 15:30  漫思  阅读(40)  评论(0编辑  收藏  举报

导航