Question origin
After wrapping the child component with ANTD’s form.create (), the parent component wants to get the instance of the child component through the wrappedComponentRef of the wrapped component. But because the subcomponent is a function Component with no instance, you cannot use the wrappedComponentRef attribute on the subcomponent. Antd also wraps the ref property to return an instance of the subcomponent instead.
The solution
Use the callback function to get the this of the child component, or to convert the functional component to a class
- A child component of the class is 🌰 :
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 =(a)= > {
this.setState({ visible: true });
};
saveFormRef = formRef= > {
this.formRef = formRef;
console.log(this.formRef, "I want to export.")}; render() {return (
<div>
<Button type="primary" onClick={this.showModal}>
New Collection
</Button>
<CollectionCreateForm
ref = {this.saveFormRef}
visible = {this.state.visible}
/>
</div>); }}Copy the code
- One child Component is function Component 🌰 :
// Change the subcomponent
function CollectionCreateForm(props){
const { visible } = props;
return(
<Modal visible={visible}>
<span> hello </span>
</Modal>)}Copy the code
Note that we can’t get the child component instance, but we can get the DOM refs in the child component.
Anyway, you can use the ref attribute inside a function component as long as it points to a DOM element or a class component, right
Parent component ref pass
So what do you do if you want to retrieve the DOM refs from a functional component in its parent?
- Ref to forwardUse:
React.forwardRef
Function wrappingfunction component
Function components cannot be given refs. Attempts to access this ref will fail. Did you mean to use React.forwardRef()
React.forwardRef((prop,ref) = >{function component})
Copy the code
eg:
import React, {forwardRef} from 'react';
function ThisWontWork() {
return <button>Text</button>;
}
const ThisWillWork = forwardRef((props, ref) = > { // React passes ref to the callback function (props, ref) =>... , as its second parameter.
return <button ref={ref}>Text</button>;// Deliver the ref parameter and assign it to button's JSX property
});
function App() {
const childRef = React.createRef();
console.log(childRef) // {current:<button></button>}
return (
<Tippy content="Tooltip">// Get the ref of the child component<ThisWillWork ref={childRef}/>
</Tippy>
);
}
Copy the code
- Using custom attributes, use the REF attribute inside a function component as long as it points to a DOM element or class component.
function CustomTextInput(props) {
return<div> <input ref={props. InputRef} /> } class Parent extends React.Component { constructor(props) { super(props); this.inputElement = React.createRef(); } render() { return ( <CustomTextInput inputRef={this.inputElement} /> ); }}Copy the code
3. Wrap a function and pass it to a subcomponent to get this or refs from an element without using a callback:
<childCom childRef={refs =>{this.refs = refs}}>... </childCom> <div ref={props. ChildRef}>hello</div> </childCom>Copy the code