How To Rerender When Refs Change
Solution 1:
If you want to trigger a re-render after the ref changes, you must use useState
instead of useRef
. Only that way can you ensure that the component will re-render. E.g.:
functionComponent() {
const [ref, setRef] = useState();
return<divref={newRef => setRef(newRef)} />
}
As described under useRef documentation:
Keep in mind that
useRef
doesn’t notify you when its content changes. Mutating the.current
property doesn’t cause a re-render. If you want to run some code when React attaches or detaches a ref to a DOM node, you may want to use a callback ref instead.
It may sometimes be better to store whatever value you are getting from the DOM node, as suggested here, instead of storing the node itself.
Solution 2:
useCallback could listen the ref changed
exportdefaultfunctionMapboxGLMap() {
const drawControlRef = useCallback(node => {
if (node !== null) {
//fetch(...) load data
}
},[]);
return(
<DrawControlref={drawControlRef }/>
)
}
Solution 3:
While the component doesn't re-render, useEffect
does receive the ref once current
is filled. So while the marked answer is also correct, it is not the idiomatic way to do it since it will cause 1 unnecessary render when setting the ref to state.
exportdefaultfunctionMapboxGLMap() {
const drawControlRef = useRef(null)
useEffect(() => {
// This has a value now.console.log(drawControlRef.current)
}, [])
return(
<DrawControlref={drawControlRef} />
)
}
And if you wish to pass the ref to custom hooks then use drawControlRef
rather than drawControlRef.current
, and then you can also access a filled out drawControlRef.current
in the useEffect
hooks in there too.
Solution 4:
You can use a callback function that useEffect
base on the change in useRef
functionuseEffectOnce(cb) {
const didRun = useRef(false);
useEffect(() => {
if(!didRun.current) {
cb();
didRun.current = true
}
})
}
Post a Comment for "How To Rerender When Refs Change"