React how to use imperative handles

React how to use imperative handles

Imperative handles in React enable you to propagate functionality up to the parent  component and in combination with the context api we could even go further.

In order to make use of this (and regarding to the React documentation it should be avoided if possible) we have to forward our component with the help of forwardRef(component). This is fairly simple, we just call it when we return the component which lets us use the components ref value by importing it as argument.

type MyComponentHandles = {
    doSomething: () => void
}

const MyComponent = (props: Props, ref: React.Ref<MyComponentHandles>): JSX.Element => {
    return (
        <View>
            // children...
        </View>
    )
}

return forwardRef(myComponent)

We can use ref now to define our components functionality we want to propagate up the component chain. To do so, we use the hook React provides us useImperativeHandle which takes our ref value as first argument and as second argument a callback function.

type MyComponentHandles = {
    doSomething: () => void
}

const MyComponent = (props: Props, ref: React.Ref<MyComponentHandles>): JSX.Element => {
    const handle = useCallback((): void => {
        // some functionality
    },[])
    
    useImperativeHandle(ref, () => {
        doSomething: handle
    })
    
    return (
        <View>
            // children...
        </View>
    )
}

return forwardRef(myComponent)

Now we could for example add some state to the component that allows us to change the components visibility or simply its styles in some way. We can then expose two functions within the handle to enable or disable a style. Once the component is mounted we can then subscribe our handles to our store via the context api and call the handles whenever we need.