I am trying to utilize React.forwardRef() and I'm scratching my head over the following issue:
It appears that IntelliJ is able to correctly interfer the type of the reference, which is FilterRef in this case.
However, I am unable to access the current value ref.current without a compilation error stating that this would not exist.
Printing it out at runtime, of course, confirms that current is an existing attribute.
Not sure what causes this issue.
Code
I am creating a reference which I want to share with a Filter component and a context-provider:
const filterRef = useRef<FilterElement>({ filters, setFilters: onSetFilters });
console.log('filterRef', filterRef);
return (
<>
<Filter ref={filterRef} />
<FilterContext.Provider value={{ ref: filterRef }}>
<Outlet />
</FilterContext.Provider>
</>
);
However, current is always null:
export const Filter = React.forwardRef<FilterElement, FilterProps>((props, ref) => {
const filterRef = useRef<FilterElement>(null);
useImperativeHandle(ref, () => filterRef.current!, []);
console.log('filter', filterRef, ref);
// ...
}

Edit 2
In order to have a separate state being managed by
Filteritself, the following can be done as well:Edit:
Based on the updated code, I think you don't need the
refat all, as you can just passfiltersandsetFiltersto both theFiltercomponent as well as theFilterContextprovider:In any case, if you want to do that, you don't need to use
forwardRef, just name your prop something else and type it asRefObject:The answer below with
useImperativeHandlerwould be used if you want to use arefinside theFiltercomponent, but also want to expose that samerefto the parent.Original answer:
Refs can either be an object with a
currentproperty, like the ones returned byuseRefor arefcallback function, so the compiler is right.You should create a new
refin yourFiltercomponent and useuseImperativeHandleto sync it with the forwarded one: