A full example Source
import React, { Component, useRef, useImperativeHandle } from "react"
import { render } from "react-dom"
import Hello from "./Hello"
import "./style.css"
class App extends Component {
constructor() {
super()
this.state = {
name: "React",
}
}
render() {
return (
<div>
<Hello name={this.state.name} />
<p>Start editing to see some magic happen :)</p>
<Parent />
</div>
)
}
}
function Parent(props) {
const refs = useRef([])
const someData = [1, 2, 3, 4, 5]
function validateChildren() {
refs.current.forEach(child => {
// in below the validate() function comes from Child comp and will be available to parent component using ref
child.validate()
})
}
return (
<>
<button onClick={validateChildren}>Validate</button>
{someData.map((data, index) => {
return <Child key={index} ref={ins => (refs.current[index] = ins)} />
})}
</>
)
}
const Child = React.forwardRef((props, ref) => {
useImperativeHandle(ref, () => ({
validate() {
// to validate this component
console.log("I'm clicked")
},
}))
return <>Some code here</>
})
render(<App />, document.getElementById("root"))
From the docs,
useImperativeHandle customizes the instance value that is exposed to parent components when using ref. As always, imperative code using refs should be avoided in most cases. useImperativeHandle should be used with forwardRef
Another example of passing ref further down Parent > Middle > Child want to call a method from Child in Parent https://stackoverflow.com/questions/57389181/unable-to-call-child-function-from-parent-using-refs-with-functional-component