Остерігайтеся lodash.memoize

Lodash memoize здається безкоштовним прискоренням. Ви обгортаєте функцію та отримуєте кеш.

Але в поведінці за замовчуванням є пастка. Вона створює ключ кешу лише на основі першого аргументу. Всі інші аргументи ігноруються.

Якщо ви використовуєте один аргумент, ви в безпеці. Якщо два або більше — ви створюєте баги.

Погляньте на цей приклад:

const add = memoize((a, b) => a + b);

add(1, 2); // Повертає 3. Результат кешується під ключем 1.
add(1, 9); // Повертає 3. Це неправильно. Мало б бути 10.

Lodash знову бачить 1. Він знаходить 1 у кеші. Він повертає старий результат. Він навіть не дивиться на 9.

Форматування валют — це поширена пастка.

const formatPrice = memoize((amount, currency) =>
  new Intl.NumberFormat('en', { style: 'currency', currency }).format(amount)
);

formatPrice(100, 'USD'); // Повертає "$100.00". Ключ — 100.
formatPrice(100, 'EUR'); // Повертає "$100.00". Це неправильно.

Другий виклик ігнорує 'EUR'. Він бачить 100 у кеші та повертає долари замість євро. Помилки немає. Попередження немає. Ви просто показуєте користувачам неправильну суму.

Ви повинні передати другий аргумент, щоб визначити ключ кешу. Цей ключ має охоплювати кожен вхідний параметр.

const formatPrice = memoize(
  (amount, currency) =>
    new Intl.NumberFormat('en', { style: 'currency', currency }).format(amount),
  (amount, currency) => `${amount}|${currency}`
);

formatPrice(100, 'USD'); // "$100.00"
formatPrice(100, 'EUR'); // "€100.00"

Ключ має фіксувати все, що змінює результат.

Наостанок: мемоїзація несе ризики. Використовуйте її лише тоді, коли функція є ресурсомісткою і часто викликається з тими самими вхідними даними. Для простих функцій просто викликайте їх. Ризик виникнення багу часто вищий, ніж отримане прискорення.

Основні висновки:

Джерело: https://dev.to/figsify/beware-of-lodashmemoize-it-only-remembers-the-first-argument-4cjl