Home > References > Web Development > Reactjs references

forwardRef and useImperativeHandle to access child components

Last updated : 29 April 2022

1. Overview

useImparetiveHandler combined with forwardRef allows us to take control over child components' input elements. This tutorial explains how to use forwardRef and useImparetiveHandler to expose components dom elements to parent components or HOC (higher-order components)

2. forwardRef vs useImperativeHandle

forwardRef allows you to pass ref objects from parent components to child components, allowing you to access child components dom element. useImperativeHandle allows you to modify the ref object passed to the useImperativeHandle hook.

  • useImperativeHandle allows you to customized and override the default dom elements return value.
  • It allows you to override or customize default dom element events with your own.

3. useImperativeHandle example with Typescript

import { forwardRef, useImperativeHandle, useRef } from "react"

interface InputProps{
}
type RefHandler = {
}
export const RefForm = () => {
    const nameRef =  useRef() as React.MutableRefObject<HTMLInputElement>;
    const focusHandler = () => {
        nameRef.current.focus()
    }
    const blurHandler = () => {
        nameRef.current.blur()
    }
    const toggleHandler = () => {
        nameRef.current.toggleAttribute("Some Value")
    }
    const clearHandler = () => {
        nameRef.current.remove()
    }
    return(
        <>
            <Input ref={nameRef}/>
            <div>
                <button onClick={focusHandler}>Focus</button>
                <button onClick={blurHandler}>Blur</button>
                <button onClick={toggleHandler}>Toggle</button>
                <button onClick={clearHandler}>Clear</button>
            </div>
        </>
    )
}

const Input = forwardRef<RefHandler,InputProps>((props, ref) => {
    const nameRef = useRef() as React.MutableRefObject<HTMLInputElement>;
    useImperativeHandle(ref, () => ({
        focus: () => {
            nameRef?.current?.focus();
        },
        blur: () => {
            alert("Some blur function")
        },
        toggleAttribute: (val: string) => {
            nameRef.current.value = val
        },
        remove: () => {
            nameRef.current.value = ""
        }
      }));
    return(
        <input type="text" name="name" value="" ref={nameRef}/>
    )
})

4. useImperativeHandle example with Javascript

import { forwardRef, useImperativeHandle, useRef } from "react"

export const RefForm = () => {
    const nameRef =  useRef()
    const focusHandler = () => {
        nameRef.current.focus()
    }
    const blurHandler = () => {
        nameRef.current.blur()
    }
    const toggleHandler = () => {
        nameRef.current.toggleAttribute("Some Value")
    }
    const clearHandler = () => {
        nameRef.current.remove()
    }
    const valueHandler = () => {
        alert(nameRef.current.value())
    }
    return(
        <>
            <Input ref={nameRef}/>
            <div>
                <button onClick={focusHandler}>Focus</button>
                <button onClick={blurHandler}>Blur</button>
                <button onClick={toggleHandler}>Toggle</button>
                <button onClick={clearHandler}>Clear</button>
                <button onClick={valueHandler}>Value</button>
            </div>
        </>
    )
}

const Input = forwardRef((props, ref) => {
    const nameRef = useRef()
    useImperativeHandle(ref, () => ({
        focus: () => {
            nameRef?.current?.focus();
        },
        blur: () => {
            alert("Some blur function")
        },
        toggleAttribute: (val) => {
            nameRef.current.value = val
        },
        remove: () => {
            nameRef.current.value = ""
        },
        value: () => {
            return nameRef.current.value + " modified"
        }
      }));
    return(
        <input type="text" name="name" value="" ref={nameRef}/>
    )
})
Lance
By: Lance
Lance is a software engineer with over 15 years of experience in full-stack software development.
Read more...

Comments are disabled

No Comments