I need to provide some custom functionality after render that uses refs.
It seems to be a perfect use case for useEffect
, but it needs to be in a custom hook so that it can be reused.
Unfortunately, passing either a ref
or its current
to a custom hook that does useEffect appears to result in different behaviour than calling useEffect
directly.
A working example looks like this:
const useCustomHookWithUseEffect = (el1, el2) => {
React.useEffect(() => {
console.log("CUSTOM Use effect...");
console.log("firstRef element defined", !!el1);
console.log("secondRef element", !!el2);
}, [el1, el2]);
}
const RefDemo = () => {
const [vis, setVis] = React.useState(false);
const firstRef = React.useRef(null);
const secondRef = React.useRef(null);
useCustomHookWithUseEffect(firstRef.current, secondRef.current);
React.useEffect(() => {
console.log("Standard Use effect...");
console.log("firstRef element defined", !!firstRef.current);
console.log("secondRef element ", !!secondRef.current);
}, [firstRef.current, secondRef.current]);
console.log("At RefDemo render", !!firstRef.current , !!secondRef.current);
return (
<div>
<div ref={firstRef}>
My ref is created in the initial render
</div>
<div className="clickme" onClick={() => setVis(true)}>
click me
</div>
{vis &&
<div ref={secondRef}>boo (second ref must surely be valid now?)</div>
}
</div>
)
}
After the first render, the custom hook does not have the defined value of firstRef, but the in-line useEffect does.
After clicking the click-me, once again the custom hook does not get the most-recent update (though now it has the firstRef value).
Is this expected?
How could I achieve the goal: be able to re-usably supply useEffect-based code that uses refs?
https://jsfiddle.net/GreenAsJade/na1Lstwu/34/
Here's the console log:
"At RefDemo render", false, false
"CUSTOM Use effect..."
"firstRef element defined", false
"secondRef element", false
"Standard Use effect..."
"firstRef element defined", true
"secondRef element ", false
Now I click the clickme
"At RefDemo render", true, false
"CUSTOM Use effect..."
"firstRef element defined", true
"secondRef element", false
"Standard Use effect..."
"firstRef element defined", true
"secondRef element ", true