admin管理员组文章数量:1395461
Across my app, there are some UX logic that needs to be shared. They are triggered by events, so I wrote 2 custom hooks. Let's call one useRefWithCalc
. The other hook is a more standard useEventListener
, similar to this one.
useRefWithCalc
calls the native useRef
, has some internal handlers for UX, then calls useEventListener
to attach those handlers. useRefWithCalc
returns the ref
created within, so another ponent can use this hook, and get the returned ref to attach to elements.
This has worked for me when the ref isn't attached to conditionally rendered elements.
The ponent looks something like this. Please take note on the 2 test logs.
const useEventListener = (event, listener, ref) => {\
...
useEffect(() => {
...
console.log("1. ref is: ", ref.current); // test logging 1.
ref.current.addEventListener(event, listener);
return () => {
ref.current.removeEventListener(event, listener);
}
}, [event, listener, ref]);
}
const useRefWithCalc = (value) => {
const ref = useRef(null);
...
const calc = () => {
// some calculations
}
...
useEventListener(event, calc, ref)
return [ref, result]
}
// works perfectly
const WorkingElement = (props) => {
const [ref, result] = useRefWithCalc(props.value);
...
return <B ref={ref} />
}
// doesn't work consistently
const ConditionalElement = (props) => {
const [state, setState] = useState(false);
const [ref, result] = useRefWithCalc(props.value)
useEffect(()=>{
if (ref && ref.current) {
ref.current.focus();
console.log("2. ref is: ", ref.current); // test logging 2
}
}, [ref])
...
return state ? <A> : <B ref={ref} />
}
The <WorkingElement />
works just as expected. The ref gets attached, and handles events with no problem.
However, in the <ConditionalElement />
, when B is mounted, sometimes times test logging 1 won't fire. Test logging 2 always fires, and the ref gets the focus correctly. But this update is not passed into useEventListener
Once <B />
gets 1 subsequent update (e.g. when user inputs something), both logs will fire correctly, and the event listner gets attached correctly, and it work just as <WorkingElement />
Sorry for not posting the exact code. I feel like my approach is convoluted and might be wrong.
Across my app, there are some UX logic that needs to be shared. They are triggered by events, so I wrote 2 custom hooks. Let's call one useRefWithCalc
. The other hook is a more standard useEventListener
, similar to this one.
useRefWithCalc
calls the native useRef
, has some internal handlers for UX, then calls useEventListener
to attach those handlers. useRefWithCalc
returns the ref
created within, so another ponent can use this hook, and get the returned ref to attach to elements.
This has worked for me when the ref isn't attached to conditionally rendered elements.
The ponent looks something like this. Please take note on the 2 test logs.
const useEventListener = (event, listener, ref) => {\
...
useEffect(() => {
...
console.log("1. ref is: ", ref.current); // test logging 1.
ref.current.addEventListener(event, listener);
return () => {
ref.current.removeEventListener(event, listener);
}
}, [event, listener, ref]);
}
const useRefWithCalc = (value) => {
const ref = useRef(null);
...
const calc = () => {
// some calculations
}
...
useEventListener(event, calc, ref)
return [ref, result]
}
// works perfectly
const WorkingElement = (props) => {
const [ref, result] = useRefWithCalc(props.value);
...
return <B ref={ref} />
}
// doesn't work consistently
const ConditionalElement = (props) => {
const [state, setState] = useState(false);
const [ref, result] = useRefWithCalc(props.value)
useEffect(()=>{
if (ref && ref.current) {
ref.current.focus();
console.log("2. ref is: ", ref.current); // test logging 2
}
}, [ref])
...
return state ? <A> : <B ref={ref} />
}
The <WorkingElement />
works just as expected. The ref gets attached, and handles events with no problem.
However, in the <ConditionalElement />
, when B is mounted, sometimes times test logging 1 won't fire. Test logging 2 always fires, and the ref gets the focus correctly. But this update is not passed into useEventListener
Once <B />
gets 1 subsequent update (e.g. when user inputs something), both logs will fire correctly, and the event listner gets attached correctly, and it work just as <WorkingElement />
Sorry for not posting the exact code. I feel like my approach is convoluted and might be wrong.
Share Improve this question asked Feb 26, 2022 at 8:37 Samson LiuSamson Liu 5601 gold badge6 silver badges24 bronze badges1 Answer
Reset to default 6In React when a ref changes, it doesn't trigger a ponent update, and useEffect
s are not triggered.
I suggest to put your ref inside a state so that effects are triggered when the ref changes :
const [ref, setRef] = useState(undefined)
return (
<B ref={setRef}/>
)
本文标签: javascriptReact useRef not updating consistently for conditionally rendered elementsStack Overflow
版权声明:本文标题:javascript - React useRef not updating consistently for conditionally rendered elements - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1744735224a2622286.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论