How to create a JSDoc of ref when using React.fowardRef and useImperativeHandle?
Asked Answered
S

3

5

I'm not using typescript in my reactjs project, but I still want to document my components with JSDocs.

The problem where is that I have a functional component with React.forwardRef and I want to create a JSDoc to the ref because I'm using useImperativeHandle and passing different values to the ref.

It's possible to document the ref using JSDoc to display the methods and properties that I pass in useImperativeHandle? If yes, how?

Where is an example of what I want

In a component I use React.fowardRef with useImperativeHandle

export const Foo = React.fowardRef((props, ref) => {

    useImperativeHandle(ref, () => ({
        myMethod,
        // other methods and properties
    }))

    return <div>{/* ... */}</div>
}

And when using the ref for that component with fooRef.current, I want to see myMethod or the other properties when I type . or press Ctrl+ Space.

Saddletree answered 31/7, 2020 at 17:33 Comment(1)
were you able to document the props?Lullaby
H
9

While I don't know if this is the perfect solution, what worked for me was simply writing a typedef for all the props (including ref), and then passing it to @type property, all in JSDoc. Here is a snippet that should work:

import React from 'react';
import PropTypes from 'prop-types';

/**
 * @typedef {Object} RefType
 * @property {Object} current
 * @property {() => void} current.methodOne
 * @property {() => void} current.methodTwo
 */

/**
 * @typedef {Object} Props
 * @property {RefType} ref
 * @property {string} value
 * @property {((event: React.ChangeEvent<HTMLInputElement>) => void) | undefined} onChange
 */

/**
 * @type {React.FC<Props>}
 */
export const Input = React.forwardRef((
  props, 
  /** @type {RefType} */
  ref) => {
  return <input ref={ref} onChange={props.onChange} value={props.value} />
})

Input.propTypes = {
  value: PropTypes.string.isRequired,
  onChange: PropTypes.func.isRequired,
};

Input.displayName = 'Input';

So when I then use the component, here is the intellisense I get in VSCode for example: Intellisense after using said component.

The intellisense should work in the entire project.

EDIT: I should explain why I included PropTypes. I faced the same issue to yours, and figured out a solution, but I also needed the dev tools to preserve component name. Dev tools would instead display the React.forwardRef instead of real component name. The displayName property will do the trick to keep the original name.

EDIT: If you need to have autocomplete inside the component itself, you can do it like image link below. I've updated the code snippet to reflect this. Autocomplete on ref argument itself.

Hama answered 5/10, 2020 at 13:14 Comment(1)
Thanks you so much, I've been looking for this for a long timeErse
P
3

Write like:

/** @type {React.MutableRefObject<YourTypeHere>} */
const ref = useRef()

Peripheral answered 24/8, 2022 at 13:42 Comment(0)
P
0

I managed to add jsDoc on the function declared on useImperativeHandle like this. In my instance, I was using Typescript but I believe you could do the same in Javascript if you add the jsDoc just above the declaration of the function inside useImperativeHandle

type ComponentProps = {}
type ComponentRefProps = {
    /**
     * here is the description of the function
     * @param param1 
     * @param param1 
     * @returns nothing for now
     */
    yourFunction: (param1: any, param2: any) => void
}
const CustomComponent = forwardRef<ComponentRefProps, ComponentProps>((props, ref) => {
    useImperativeHandle(ref, () => ({
        yourFunction(param1, param2) {
            
        },
    }), [])
    return <Text>This is a component</Text>
})
Pernicious answered 6/2 at 4:43 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.