primefaces / primefaces/primereact
ForwardedRef-Components: ref cannot be accessed on useLayoutEffect lifecycle
Nobody has claimed this yet.
- Dominant language
- CSS
- Stars
- 8.3k
- Forks
- 1.2k
- PR merge metrics
- No merged PRs in 30d
Description
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
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Inspect the forwarded-ref implementations in Button and InputText, including ObjectUtils.combinedRefs and the elementRef initialization shown in the issue. Reproduce the case with a parent useLayoutEffect, then add or update a regression test; done means the forwarded ref is available when that effect runs.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- react
- Domain
- frontend
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 38/100