-1

Let's say I have a variable that depends on a prop, and I declare it in a simple way:

const isLeapYear = year % 4 === 0; // year is a prop

Now, let's imagine I have a complex function, and I "memorize" its result using useMemo:

const result = useMemo(() => console.log('complex function', isLeapYear), [isLeapYear]);

So here’s my question: Will result be recalculated every time just like isLeapYear, since isLeapYear changes with each render? Would it be a better idea to also declare isLeapYear using useMemo?

2
  • "Will result be recalculated" - yes. "Would it be a better idea" - no, but if you don't use isLeapYear anywhere but result, it makes sense to declare it inside existing useMemo Commented Jun 12 at 10:51
  • "since isLeapYear changes with each render?" - why do you think it does that? Does the year prop change with each render? And does it always toggle between being divisible by 4 and not? Commented Jun 12 at 19:21

1 Answer 1

2

since isLeapYear changes with each render

I don't see why it would change on every render. If you mean it's a newly-defined variable that's true, but useMemo compares the old and new values with Object.is (similar to ===), so all that matters is if the values are the same.

If isLeapYear is, say, true on one render and true on the next, then the useMemo for result will not run. Only if it toggles from true to false or vice versa will the memoization break.

Now, if you have an object in a dependency array, then you may need to memoize that object so that it's the same object reference. But primitives like booleans don't need this

const example = { isLeapYear: year % 4 === 0 };
const result = useMemo(
  () => /* ... some calculation using example */, 
  [example] // <--- Problem! example will be a new object on every render.
)

The above code will break the memoization on ever render. The objects may have the same contents, but they are different objects. If all you're using is the isLeapYear part you can change your dependency array to [example.isLeapYear]. But if the whole object is needed, you'll need to memoize it.

const example = useMemo(
  () => ({ isLeapYear: year % 4 === 0 }),
  [year]
)
const result = useMemo(
  () => /* ... some calculation using example */, 
  [example]
)
Sign up to request clarification or add additional context in comments.

1 Comment

You'd probably even use const example = useMemo(() => ({ isLeapYear: year % 4 === 0 }), [year % === 0]) (or just const isLeapYear = year % 4 === 0; const example = useMemo(() => ({ isLeapYear }), [isLeapYear])) to avoid creating a new object if its contents don't change.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.