I'm creating an app where I need to create an object on initial render and keep it for the whole component life.
My code looks somehow like that right now:
function Component() {
const obj = useRef(new Smth());
return (
<div>
<button onClick={obj.current.p}>p</button>
<button onClick={obj.current.c}>c</button>
</div>
);
};
The React documentation says:
useRef returns a mutable ref object whose .current property is initialized to the passed argument (initialValue). The returned object will persist for the full lifetime of the component.
from: https://reactjs.org/docs/hooks-reference.html#useref
and it seems that I use it properly. Yet, Hooks FAQ says:
You might also occasionally want to avoid re-creating the useRef() initial value. For example, maybe you want to ensure some imperative class instance only gets created once:
function Image(props) {
// ⚠️ IntersectionObserver is created on every render
const ref = useRef(new IntersectionObserver(onIntersect));
// ...
}
useRef does not accept a special function overload like useState. Instead, you can write your own function that creates and sets it lazily:
function Image(props) {
const ref = useRef(null);
// ✅ IntersectionObserver is created lazily once
function getObserver() {
if (ref.current === null) {
ref.current = new IntersectionObserver(onIntersect);
}
return ref.current;
}
// When you need it, call getObserver()
// ...
}
from: https://reactjs.org/docs/hooks-faq.html#is-there-something-like-instance-variables
So does the initial value get recreated or not?
CodePudding user response:
So does the initial value get recreated or not?
Yes the initial value can be re created but then it is discarded. Because of this you can keep some value inside useRef
and it will not be lost between re renders, you can also modify it as you like.
It is similar with useState
, if you pass a value to its constructor it gets recomputed but then it gets discarded. You can pass function to useState
which will only be executed once. Apparently based on the docs, useRef
doesn't have such option. But you can simulate it based on the docs:
// ✅ IntersectionObserver is created lazily once
function getObserver() {
if (ref.current === null) {
ref.current = new IntersectionObserver(onIntersect);
}
return ref.current;
}