React Memoize Hooks should not be used fruitlessly

  • REACT_USELESS_MEMOIZE_HOOK
  • Code Quality
  • Low
  • react

This rule applies when useMemo and useCallback Hooks are used fruitlessly.

useMemo and useCallback are handy tools for memoizing values to avoid expensive computations and maintain referential equality.

However, some caution is needed because they become useless in the following situations:

  1. The second dependencies array argument is not provided. In this case, the memoization becomes meaningless because the value is always recomputed. It is recommended to provide the precise dependencies or an empty array if computing only once was intended.
  2. The argument function of useMemo always returns the same value. The return value of the function is used as the memoized value. If it is always the same, there is no point in memoizing it. One possible case is that memoizing the function itself was intended instead of the return value. In that case, you should use useCallback.

Noncompliant Code Example

View with compliant examples side by side
import React, { useMemo } from 'react';

// Example 1
function HelloColor(props) {
    let memoized = useMemo( // REACT_USELESS_MEMOIZE_HOOK alarm because the second argument is not provided.
        () => ({ color: props.color })
    );
    return <div style={memoized}>Hello</div>;
}

// Example 2
function HelloClick(props) {
    let memoized = useMemo( // REACT_USELESS_MEMOIZE_HOOK alarm because the argument function always returns the same value.
        () => { props.handler(props.arg) },
        [props.handler, props.arg]
    );
    return <div onClick={memoized}>Hello</div>;
}

Compliant Code Example

View with noncompliant examples side by side
import React, { useMemo } from 'react';

// Example 1
function HelloColor(props) {
    let memoized = useMemo(
        () => ({ color: props.color }),
        [props.color]
    );
    return <div style={memoized}>Hello</div>;
}

// Example 2
function HelloClick(props) {
    let memoized = useCallback(
        () => { props.handler(props.arg) },
        [props.handler, props.arg]
    );
    return <div onClick={memoized}>Hello</div>;
}

Version

This rule was introduced in DeepScan 1.27.0.

See

  • useCallback

  • useMemo

  • eslint-plugin-react-hooks warning: React Hook useCallback does nothing when called with only one argument. Did you forget to pass an array of dependencies?