primereact
primereact copied to clipboard
ForwardedRef-Components: ref cannot be accessed on useLayoutEffect lifecycle
Describe the bug
A given ref to component can not be accessed in useLayoutEffect. The problem exists in Button and InputText, I think other components may also be affected, maybe only those which do not use useImperativeHandle.
function MyButton(){
const ref = useRef(null);
useLayoutEffect(() => ref.current.focus());
return <Button ref={ref}>Click</Button>
}
Error: ref.focus is null
Here are some parts from sourcecode of Button:
export const Button = React.forwardRef((inProps, ref) => {
const elementRef = React.useRef(ref);
React.useEffect(() => {
ObjectUtils.combinedRefs(elementRef, ref);
}, [elementRef, ref]);
const rootProps = mergeProps(
{
ref: elementRef,
(...)
},
(...)
);
return (
<>
<button {...rootProps}>
(...)
</button>
</>
);
}
useEffect will synchronize both ref. Therefore useLayoutEffect which runs earlier can not access the forwardedRef.
I do not understand why ref should be initValue for elementRef.
const elementRef = React.useRef(ref);
Possible solution with custom hook:
function useForwardedRef(forwardedRef){
const ref= React.useRef();
if(forwardedRef) return forwardedRef;
return ref;
}
export const Button = React.forwardRef((inProps, ref) => {
const elementRef = useForwardedRef(ref);
return (
<>
<input ref={elementRef} {...rootProps} />
(...)
</>
}
Maybe Utils.combinedRef will be obsolete.
Reproducer
No response
System Information
react 18.2
primereact 10.5.1
Steps to reproduce the behavior
No response
Expected behavior
No response