Call child method from parent React.js component
Posted on January 28, 2021 in
2 min read
In this sample I wanted to figure out how to call from within a parent component a child component' method in a React.js app.
I wanted to explore both the Class and Functional version as well.
The parent wrapper
Here the parent code:
import CChild from './CChild'
import FChild from './FChild'
function Mock (props) {
const fref = useRef()
const cref = useRef()
const handleClick = e => {
fref.current.setFromOutside('HELLO from Parent')
cref.current.setFromOutside('HELLO from Parent')
}
return (
<div>
<button onClick={handleClick}>Show Me!</button>
<FChild ref={fref} />
<CChild ref={cref} />
</div>
)
}
There are two children components and a button to trigger the call.
The method setFromOutside
belongs to the children definition.
The children components
Here the code of the Class version:
import React from 'react'
class Child extends React.Component {
constructor (props) {
super(props)
this.state = { message: 'Waiting' }
}
setFromOutside (msg) {
this.setState({ message: msg })
}
render () {
return (
<h1>{this.state.message}</h1>
)
}
}
export default Child
The Class version is pretty straighforward, the method setFromOutside
is public, thus, it's visible from the parent by means of the child reference.
Here the Functional version:
import { useState, forwardRef, useImperativeHandle } from 'react'
function Child (props, ref) {
const [message, setMessage] = useState('Waiting')
useImperativeHandle(ref, () => ({
setFromOutside (msg) {
setMessage(msg)
}
}), [])
return (
<h1>{message}</h1>
)
}
export default forwardRef(Child)
Well, in this implementation there are some notable things to say:
- The public method needs to be included in the
useImperativeHandle
hook. - Also, you have to export the component with
forwardRef
HOC function. - By exporting the component with
forwardRef
, the Function now has two arguments,props
andref
, where the latter needs to be used inuseImperativeHandle
hook.
Ouch, that's not really "natural" to me, but still.