Antd踩坑 — 當子組件是 function component 時使用 wrappedComponentRef

問題起源

父組件想拿到子組件的 ref,使用 antd 的 Form.create() 包裝子組件以後,能夠經過包裝後的組件的 wrappedComponentRef 拿到子組件的實例。可是由於子組件是一個 function component 沒有實例,致使不能在子組件上使用 wrappedComponentRef 屬性(本質上使用了 ref 屬性得到子組件的實例 _class,且 antd 對原本的 ref 屬性另外包裝了一下,返回的不是子組件的實例 _class)。html

解決辦法

使用回調函數拿到子組件的 this,或者將函數式組件轉化爲一個 classreact

  • 一個子組件是 class 的🌰:
class CollectionCreateForm extends React.Component {
    render() {
      const { visible } = this.props;
      return (
        <Modal visible={visible}> <span> hello </span> </Modal>
      );
    }
}

export default class App extends React.Component {
  state = {
    visible: false,
  };
  showModal = () => {
    this.setState({ visible: true });
  };
  saveFormRef = formRef => {
    this.formRef = formRef;
    console.log(this.formRef, "我要輸出")
  };

  render() {
    return (
      <div> <Button type="primary" onClick={this.showModal}> New Collection </Button> <CollectionCreateForm ref = {this.saveFormRef} visible = {this.state.visible} /> </div> ); } } 複製代碼

  • 一個子組件是 function Component 的🌰:
// 子組件改一下就行
function CollectionCreateForm(props){
  const { visible } = props;
    return(
        <Modal visible={visible}> <span> hello </span> </Modal>
      )
}
複製代碼

注意了咱們雖然拿不到子組件實例,可是能夠拿到子組件中 DOM refs。數組

無論怎樣,你能夠在函數組件內部使用 ref 屬性,只要它指向一個 DOM 元素或 class 組件antd

父子組件 ref 傳遞

那麼若是想在父組件中拿到函數式組件裏面的 DOM refs 應該怎麼作呢?app

  1. ref 轉發:使用 React.forwardRef 函數包裝一下 function component

Function components cannot be given refs. Attempts to access this ref will fail. Did you mean to use React.forwardRef()dom

React.forwardRef((prop,ref)=>{function component}) 複製代碼

eg:函數

import React, {forwardRef} from 'react';

function ThisWontWork() {
  return <button>Text</button>;
}

const ThisWillWork = forwardRef((props, ref) => { // React 傳遞 ref 給 forwardRef 內函數 (props, ref) => ...,做爲其第二個參數。
  return <button ref={ref}>Text</button>;// 下發 ref 參數,並將其指定給 button 的JSX屬性
});

function App() {
const childRef = React.createRef(); 
console.log(childRef) // {current:<button></button>}
  return (
    <Tippy content="Tooltip"> // 拿到子組件的 ref <ThisWillWork ref={childRef}/> </Tippy> ); } 複製代碼
  1. 使用自定義屬性,在函數組件內部使用 ref 屬性,只要它指向一個 DOM 元素或 class 組件。
function CustomTextInput(props) {
  return (
    <div>
      <input ref={props.inputRef} /> // 取 props 裏面的屬性
    </div>
  );
}

class Parent extends React.Component {
  constructor(props) {
    super(props);
    this.inputElement = React.createRef();
  }
  render() {
    return (
      <CustomTextInput inputRef={this.inputElement} />
    );
  }
}
複製代碼

3.本身封裝一個函數傳遞到子組件裏面去,拿到子組件的 this 或者某個元素的 refs 不使用回調函數的方式:ui

// 父組件中
<childCom childRef={ refs =>{ this.refs = refs}}>...</childCom> 
// 子組件中
<childCom>
    <div ref={props.childRef}>hello</div>
</childCom>
複製代碼
相關文章
相關標籤/搜索