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
.
Creating Refs Refs are created using React.createRef() and attached to React elements via the ref attribute. Refs are commonly assigned to an instance property when a component is constructed so they can be referenced throughout the component.
In child component, we create Refs by using React. createRef() and then attached to React elements via the ref attribute. // EXPLANATION: a reference to the node becomes accessible at the current attribute of the ref. In the parent component, we can get a reference to the Input component and call its focus() method.
To create a ref in a functional component we use the useRef() hook which returns a mutable object with a . current property set to the initialValue we passed to the hook. This returned object will persist for the full lifetime of the component. Thus, throughout all of its re-rendering and until it unmounts.
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.
Write like:
/** @type {React.MutableRefObject<YourTypeHere>} */
const ref = useRef()
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With