Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Do default parameters need to be in useCallback dependency array?

The title is explanatory enough, here is an example of such a case:

const handleDateChange = useCallback((startDate = defaultStartDate, endDate = defaultEndDate) => {
      // Do something
}, [defaultStartDate, defaultEndDate]);

Do defaultStartDate and defaultEndDate need to be included in the dependency array (like in my example)?

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

>Solution :

Yes, because they’re referenced by the function, so the previous version of the function referencing the old values cannot be reused when the values change. It’s just like using those variables in the function body.

Your handleDateChange is effectively¹ the same as this, which makes it more obvious why you need those defaults in the dependency array:

const handleDateChange = useCallback(
    (startDate, endDate) => {
        if (startDate === undefined) {
            startDate = defaultStartDate;
        }
        if (endDate === undefined) {
            endDate = defaultEndDate;
        }
        // Do something
    },
    [defaultStartDate, defaultEndDate]
);

In a comment, you’ve asked:

In your code snippet you reassign the parameter in de body, in my example i do it in the parameters. Doesn’t reassigning have different behaviour? Just like how Nullish coalescing (??) for example is different in this case?

No, the above is how default parameter values work. They’re evaluated (if needed) during the call to the function, not (for instance) when the function is created. The JavaScript engine inserts code at the very beginning of your function (in a wrapper scope; details) that does the if and assignment above. (It’s very similar to nullish coalescing, but null doesn’t trigger the default, only undefined does, as in the code above). Here’s an example:

function alloc() {
    const value = Math.random();
    console.log(`alloc called, returning ${value}`);
    return value;
}

function example(p = alloc()) {
    console.log(`p = ${p}`);
}

console.log("Call with a value other than `undefined` (no call to `alloc`):");
example(42);
console.log();

console.log("Call without a value (calls `alloc`):");
example();
console.log();

console.log("Call with `undefined` (also calls `alloc`):");
example(undefined);
console.log();

console.log("Call with `null` (doesn't call `alloc`):");
example(null);
.as-console-wrapper {
    max-height: 100% !important;
}

¹ "effectively" — there are two very minor differences: 1. the length property of your function using default parameter values is 0, whereas it’s 2 in my rewrite; 2. there’s a wrapper scope involved that I haven’t tried to replicate in this simple example (see my answer here for details). But the above is fundamentally how they work.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading