Hareesh
Hareesh

Reputation: 1587

How to get the ref of a child component inside parent component in ReactJS

I have a parent component and a child component as following.

Parent component:

constructor(){
    this.refs = React.createRef();
}

setRef(ref) {
    console.log(ref)
}

handleChange(e) {
    console.log(e)
}

render() {
    return(
        <ChildComponent ref={this.setRef} handleChange={this.handleChange.bind(this)}/>
    )
}

Child Component:

render() {
    return(
        <input type="text" ref={this.props.ref} onChange={this.props.handleChange.bind(this)} > </input>
    )
}

What changes should I do to get the ref value inside the handleChange() function in parent component? Thanks in advance.

Upvotes: 4

Views: 10509

Answers (3)

user6612182
user6612182

Reputation:

If I´m reading correctly you want to access the input element from the parent component?

You have to use another name for your prop as ref is a keyword prop which will automatically assign the component the given variable.

<ChildComponent inputRef={this.setRef} handleChange={this.handleChange.bind(this)}/>

class ChildComponent extends Component {
    render() {
        return(
            <input type="text" ref={this.props.inputRef} onChange= {this.props.handleChange.bind(this)} > </input>
        );
    }
}

Based on how you want to access the ref you can either set this.refs directly to the prop or set it inside your setRef function.

// either `this.refs` and then usable through `this.refs.current`
<ChildComponent inputRef={this.refs} {...} />

// or `this.setRef` and assign it yourself
setRef = (ref) => {this.refs = ref;}

Upvotes: 2

Guichi
Guichi

Reputation: 2343

ref work only on native dom element, to make ref work on user defined Component, you need this:

https://reactjs.org/docs/forwarding-refs.html

Upvotes: 0

skyboyer
skyboyer

Reputation: 23753

ref(as well as key btw) is very special prop. It is not accessible in child by this.props.ref.

Shortest way is to use different prop to pass ref forward and backward:

class Parent ...
    render() {
    ...
        <Child inputRef={this.inputRef} />

class Child 
...
    render() {
        <input ref={this.props.inputRef} ...

It's most flexible since you may access different ref inside you child component(e.g. inputRef + scrollableContainerRef + popupRef)

But in some cases you want to compose new component for existing code base. Say <input>'s replacement. Sure, in this case you would avoid changing all <input ref={...} /> onto <MyInput refProp={...}>.

Here you may use React.forwardRef. It feels the best with functional components like

export Child = React.forwardRef((props, forwardedRef) => {
    ...
    return ...
        <input ref={forwardedRef} />
})

But for class-based component you would rather use ref-prop with different name:

class Child
...
    render()
        return
        ...
        <input ref={this.props.forwardedRefName} />

export ChildWithForwardRef = React.forwardRef((props, ref) => <Child forwardedRefName={ref} {...props} />)

PS since you will consume what forwardRef returns rather initial component(Child) you may want to specify displayName for it. This way you may be able find it later say with enzyme's find() or easy recognize element in browser's React DevTools

Upvotes: 2

Related Questions