A Child component method can call the parent component method using React Refs.
We need three hooks for functional components. They are useRef, forwardRef, and useImperativeHandle.
useImperativeHandle(ref, () => ({
childFunction : (val: string): void => {
alert(val)
}
}))
Here is the complete code snippet in Typescript.
import React, { forwardRef, useImperativeHandle, useRef, useState } from "react"
interface InputProps {
name: string
}
type RefHandler = {
childFunction: (val: string) => void
}
export const Form = () => {
const childRef = useRef() as React.MutableRefObject<RefHandler>;
const callChildFunction = (val: string) => {
childRef.current.childFunction(val);
}
return (
<>
<Input name="name" ref={childRef}/><button onClick={() => callChildFunction("From Parent")}>Ok</button>
</>
)
}
const Input = forwardRef<RefHandler,InputProps>((props, ref) => {
useImperativeHandle(ref, () => ({
childFunction : (val: string): void => {
alert(val)
}
}))
return(
<div><input name={props.name}/></div>
)
})
If your project is in Javascript, here is the same version with Javascript.
import { forwardRef, useImperativeHandle, useRef } from "react"
export const Form = () => {
const childRef = useRef()
const callChildFunction = (val) => {
childRef.current.childFunction(val);
}
return (
<>
<Input name="name" ref={childRef}/><button onClick={() => callChildFunction("From Parent")}>Ok</button>
</>
)
}
const Input = forwardRef((props, ref) => {
useImperativeHandle(ref, () => ({
childFunction : (val) => {
alert(val)
}
}))
return(
<div><input name={props.name}/></div>
)
})
For those who use class based components, here is the class component version of the same. If you use a React version > 16.8, consider upgrading your React component to a functional component.
import React, { Component } from "react";
export class Form extends Component{
constructor(props) {
super(props);
this.childRef = React.createRef()
}
callChildFunction = (val) => {
this.childRef?.current?.childFunction(val);
}
render() {
return(
<>
<Input name="name" ref={this.childRef}/><button onClick={() => this.callChildFunction("From Parent")}>Ok</button>
</>
)
}
}
export class Input extends Component{
childFunction = (val) => {
alert(val)
}
render() {
return(
<div><input name={this.props.name}/></div>
)
}
}