【问题标题】:Ant design 4.0.1 - Access methods of child form inside class component from parent componentAnt design 4.0.1 - 从父组件访问类组件内子窗体的方法
【发布时间】:2020-03-05 16:53:00
【问题描述】:

从 ant v3.x 迁移到 v4.0.1 后,我无法再从其父组件访问子窗体的方法。

在 3.x 版本中,我可以执行类似以下操作:

//Parent component - TestParent
import * as React from 'react';
import {createRef} from 'react';


export default class TestParent extends React.Component<{}, {}> {
  private formRef = createRef<any>();

  getFields = () => {
    const {form} = formRef.current.props;
    form.validateFields... ///etc
  }

  render() {
    return (
      <FormComponent
        wrappedComponentRef={this.formRef}
      />
      <Button onClick={() => {this.getFields()}>Button<Button/>
    );
  }
}


//Child component - FormComponent
import React from 'react';
import {Input, Form} from 'antd';

interface IProps {
  form: any;
}

class FormComponentContainer extends React.Component<Props, {}> {
   constructor(props: IProps) {
    super(props);
   }

  render() {
    const {form} = this.props;
    const {getFieldDecorator} = form;

    return (
      <Form>
        <Form.Item label="Full Name" colon={false}>
          {getFieldDecorator('name', {
            rules: [{required: true, message: 'Please enter your name'}]
          })(<Input placeholder="Please enter your name" />)}
        </Form.Item>
      </Form>
    );
  }
}

export const FormComponent: any = Form.create<Props>({
  name: 'form'
})(FormComponentContainer);

我可以使用formRef 访问子表单字段。

但是,自从迁移到 ant 4.0.1 后,我无法再使用新表单组件上的 ref 属性访问表单字段:

//Parent component - TestParent
import * as React from 'react';
import {createRef} from 'react';


export default class TestParent extends React.Component<{}, {}> {
  private formRef = createRef<any>();

  getFields = () => {
    const {form} = formRef.current.props;
    form.validateFields... ///etc
  }

  render() {
    return (
      <FormComponent
        formRef={this.formRef}
      />
      <Button onClick={() => {this.getFields()}>Button<Button/>
    );
  }
}


//Child component - FormComponent
import React from 'react';
import {Input, Form} from 'antd';

interface Props {
  formRef: any;
}

export default class FormComponentContainer extends React.Component<Props, {}> {
   constructor(props: Props) {
    super(props);
   }

  render() {
       return (
      <Form ref={this.props.formRef}>
        <Form.Item
          label="Full Name"
          colon={false} 
          name="name"
          rules={[{required: true, message: 'Please enter your name'}]}
        >
          <Input placeholder="Please enter your name" />
        </Form.Item>
      </Form>
    );
  }
}

我有什么遗漏吗?父子组件都需要是类组件,而不是函数组件。

【问题讨论】:

    标签: reactjs typescript antd


    【解决方案1】:

    如果这是在您的最终代码中,则不会,

    但是

    formRef.current 已经是 ref 的形式,

    所以使用它应该只是

    getFields = () => {
        const form = formRef.current;
        form.validateFields... ///etc
      }
    

    https://ant.design/components/form/#components-form-demo-control-ref

    如果您只想验证,您可以使用新的onFinish 回调

    【讨论】:

    • 不幸的是,这不起作用,我需要访问表单的某些字段,所以 onFinish 方法是不够的
    • 您是否尝试过仅使用 formRef.current 而不是 formRef.current.props?
    【解决方案2】:

    我认为您可以使用 react ref 转发 (https://reactjs.org/docs/forwarding-refs.html#forwarding-refs-to-dom-components) 来解决您的问题。

    下面是一个具体的例子,向你展示如何在 antd 中使用 ref 转发:

    子组件:

    import { Form, Input } from 'antd'
    
    const ChildComponent = React.forwardRef((props, ref) => (
      <Form ref={ref} layout="vertical" name="item">
        <Form.Item
          name="designation"
          label="designation"
          rules={[{ required: true, message: 'mandatory' }]}
        >
          <Input />
        </Form.Item>
    
        <Form.Item
          name="quantity"
          label="quantity"
          rules={[{ required: true, message: 'mandatory' }]}
        >
          <Input />
        </Form.Item>
        <Form.Item name="ean" label="ean">
          <Input />
        </Form.Item>
        <Form.Item
          name="sku"
          label="sku"
          rules={[{ required: true, message: 'mandatory' }]}
        >
          <Input />
        </Form.Item>
        <Form.Item
          name="price"
          label="price"
          rules={[
            {
              required: true,
              message: 'mandatory',
            },
          ]}
        >
          <Input />
        </Form.Item>
      </Form>
    ))
    
    export default ChildComponent
    

    父组件:

    import React, { useRef } from 'react'
    import { Button } from 'antd'
    import ChildComponent from './ChildComponent'
    
    function ParentComponent() {
      const ref = useRef(null)
    
      function handleClick() {
        ref.current.validateFields().then(values => {
          console.log(values)
        })
      }
    
      return (
        <>
          <Button onClick={handleClick}>Validate</Button>
          <ChildComponent ref={ref} />
        </>
      )
    }
    
    export default ParentComponent
    

    【讨论】:

      猜你喜欢
      • 2017-11-08
      • 1970-01-01
      • 1970-01-01
      • 2020-04-21
      • 1970-01-01
      • 2020-07-29
      • 1970-01-01
      • 2019-06-29
      • 1970-01-01
      相关资源
      最近更新 更多