@arthurgeron/eslint-plugin-react-usememo

中文文档
3.0.1发布于 2026/05/11MITESM + CJS近 30 天下载 6.3万

This plugin enforces the wrapping of complex objects or functions (which might generate unnecessary renders or side-effects) in useMemo or useCallback. It also allows you to programmatically enforce the wrapping of functional components in memo, and

原始使用文档
文档目录13 节
  1. Purpose
  2. Guidelines for Memoization
  3. There are two primary rules for situations where dynamic ob…
  4. It is not recommended to use memoization in the following c…
  5. Installation
  6. Compatibility
  7. ESLint v9 Configuration (eslint.config.js)
  8. Examples
  9. Rule #1: require-usememo (recommended)
  10. Rule #2: require-memo
  11. Rule #3: require-usememo-children
  12. Contributing
  13. Conclusion

ESLint-Plugin-React-UseMemo

This plugin enforces the wrapping of complex objects or functions (which might generate unnecessary renders or side-effects) in useMemo or useCallback. It also allows you to programmatically enforce the wrapping of functional components in memo, and that all props and dependencies are wrapped in useMemo/useCallback.

Purpose

The objective is to ensure that your application's component tree and/or expensive lifecycles (such as React Native's FlatLists, useEffect, useMemo, etc.) only re-calculate or render again when absolutely necessary. By controlling expensive expressions, you can achieve optimal scalability and performance for your application.

Note: Use of memoization everywhere is not advised, as everything comes with a cost. Overusing memoization might slow down your application instead of speeding it up.

Guidelines for Memoization

For more details, please refer to React's documentation on hooks, re-rendering and memoization.

There are two primary rules for situations where dynamic objects should be memoed:

  1. Variables or expressions that return non-primitive objects or functions passed as props to other components.

    Incorrect

    function Component({ incomingData }) {
      const complexData = {
        ...incomingData,
        checked: true,
      }; // generated each render, breaks hooks shallow comparison
    
      return <SomeComponent data={complexData} />;
    }
    

    Correct

    function Component({ incomingData }) {
      const complexData = useMemo(
        () => ({
          ...incomingData,
          checked: true,
        }),
        [incomingData],
      ); // generated only when incomingData changes
    
      return <SomeComponent data={complexData} />;
    }
    
  2. Variables or expressions that return non-primitive objects returned from custom hooks.

    Incorrect

    function useMyData({ incomingData }) {
      const parsedData = parseData(incomingData); // generated each render
    
      return parsedData; // Will result in loops passed as a dependency in other hooks(e.g. useMemo, useCallback, useEffect).
    }
    

    Correct

    function useMyData({ incomingData }) {
      const parsedData = useMemo(() => parseData(incomingData), [incomingData]); // generated only when incomingData changes
    
      return parsedData; // Won't generate loops if used as a dependency in hooks.
    }
    
  • When the resulting value (expression or variable) is primitive (string, number, boolean).

    Incorrect

    function Component() {
      const width = useMemo(() => someValue * 10, []); // results in integer, wouldn't break hooks' shallow comparison; Memoizing this would only reduce performance
    
      return <SomeComponent width={width} />;
    }
    

    Correct

    function Component() {
      const width = someValue * 10;
    
      return <SomeComponent width={width} />;
    }
    
  • If you're passing props to a native component of the framework (e.g. Div, Touchable, etc), except in some instances in react-native (e.g. FlatList).

    Incorrect

    function Component() {
      const onClick = useCallback(() => {}, []);
    
      return <div onClick={onClick} />;
    }
    

    Correct

    function Component() {
      const onClick = () => {};
    
      return <div onClick={onClick} />;
    }
    
  • Values that can be a global/context outside the react Context. Incorrect

    function Component() {
      const breakpoints = [100];
    
      return <Modal breakpoints={breakpoints}>
    }
    

    Correct

    const breakpoints = [100];
    
    function Component() {
      return <Modal breakpoints={breakpoints}>
    }
    

Installation

Install it with yarn:

yarn add @arthurgeron/eslint-plugin-react-usememo --dev

or npm:

npm install @arthurgeron/eslint-plugin-react-usememo --save-dev

Compatibility

This plugin targets ESLint v9+ (flat config). ESLint v8 is no longer supported. The package exposes named exports only.

ESLint v9 Configuration (eslint.config.js)

Option 1: Use the plugin directly

import { flatConfig } from "@arthurgeron/eslint-plugin-react-usememo";

export default [
  {
    files: ["**/*.js", "**/*.jsx", "**/*.ts", "**/*.tsx"],
    languageOptions: {
      ecmaVersion: 2020,
      sourceType: "module",
      parserOptions: {
        ecmaFeatures: {
          jsx: true,
        },
      },
    },
    plugins: {
      "@arthurgeron/react-usememo": flatConfig,
    },
    rules: {
      "@arthurgeron/react-usememo/require-usememo": "error",
      "@arthurgeron/react-usememo/require-memo": "error",
      "@arthurgeron/react-usememo/require-usememo-children": "error",
    },
  },
];
import { flatConfig } from "@arthurgeron/eslint-plugin-react-usememo";

export default [
  flatConfig.configs.recommended,
];

Option 3: CommonJS syntax

const { flatConfig } = require("@arthurgeron/eslint-plugin-react-usememo");

module.exports = [
  {
    plugins: {
      "@arthurgeron/react-usememo": flatConfig,
    },
    rules: {
      "@arthurgeron/react-usememo/require-usememo": "error",
      "@arthurgeron/react-usememo/require-memo": "error",
      "@arthurgeron/react-usememo/require-usememo-children": "error",
    },
  },
];

For migration guidance, please refer to our ESLint v9 Migration Guide.

Examples

For a working example of ESLint v9 (flat config), please check the examples directory.

This rule requires complex values (objects, arrays, functions, and JSX) that get passed props or referenced as a hook dependency to be wrapped in useMemo() or useCallback().

One of the great features of this rule is its amazing autofix functionality. It intelligently wraps necessary components with useMemo() or useCallback(), making your code more efficient and saving you valuable time.

For detailed examples, options available for this rule, and information about the autofix functionality, please refer to our rules documentation.

Rule #2: require-memo

This rule requires all function components to be wrapped in React.memo().

For detailed examples and usage of this rule, please refer to our rules documentation

Rule #3: require-usememo-children

This rule requires complex values (objects, arrays, functions, and JSX) that get passed as children to be wrapped in useMemo() or useCallback().

For detailed examples and options available for this rule, please refer to our rules documentation.

Contributing

This project uses Yarn as its package manager. A preinstall script will reject npm install to keep the lockfile consistent — please use yarn install when working locally.

Conclusion

By efficiently using useMemo, useCallback, and React.memo(), we can optimize our React and React Native applications. It allows us to control the re-calculation and re-rendering of components, offering better scalability and performance.

版本与发布记录

@arthurgeron/eslint-plugin-react-usememo 共发布 55 个版本,首次发布于 2022/07/22;过去 12 个月发布了 2 个版本。

版本发布日期距今
3.0.1latest2026/05/115 个月前
3.0.02026/01/319 个月前
2.5.02025/04/111.6 年前
2.5.0--beta5beta2025/04/031.6 年前
2.5.0--beta42025/04/011.6 年前
2.5.0--beta32025/04/011.6 年前

关于 @arthurgeron/eslint-plugin-react-usememo 的常见问题

@arthurgeron/eslint-plugin-react-usememo 是什么?

This plugin enforces the wrapping of complex objects or functions (which might generate unnecessary renders or side-effects) in useMemo or useCallback. It also allows you to programmatically enforce the wrapping of functional components in memo, and

如何安装 @arthurgeron/eslint-plugin-react-usememo?

在项目目录运行 npm install @arthurgeron/eslint-plugin-react-usememo,或使用 pnpm add / yarn add / bun add。它还需要宿主项目提供 peer 依赖:eslint(^9.0.0)。npm 7 及以上与 pnpm 8 及以上默认会自动安装必需的 peer 依赖,Yarn 需要手动安装。

@arthurgeron/eslint-plugin-react-usememo 支持 TypeScript 吗?

该包的 package.json 没有声明类型入口。需要类型提示时,可以在 npm 上查找社区维护的 @types/arthurgeron__eslint-plugin-react-usememo 是否存在。

@arthurgeron/eslint-plugin-react-usememo 支持 ESM 还是 CommonJS?

同时提供 ES Module 与 CommonJS 入口,import 和 require() 都可以使用,打包工具会自动选择合适的版本。

@arthurgeron/eslint-plugin-react-usememo 可以商用吗?

@arthurgeron/eslint-plugin-react-usememo 使用 MIT 许可。宽松许可:允许商业使用、修改和再分发,通常只需在分发时保留原版权与许可声明。以上为概括,不构成法律意见,请以许可原文为准。

@arthurgeron/eslint-plugin-react-usememo 的下载量有多少?

根据 npm 官方下载统计,@arthurgeron/eslint-plugin-react-usememo 在 2026/10/07 – 2026/11/05 这 30 天内被下载 63,234 次,日均约 2,108 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@arthurgeron/eslint-plugin-react-usememo 还在维护吗?

最新版本 3.0.1 发布于 2026/05/11(5 个月前);至今共发布 55 个版本,其中过去 12 个月发布了 2 个;首次发布于 2022/07/22。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。