eslint-plugin-react-hooks - офіційний плагін ESLint від команди React. З версії 6-7 він містить не лише два класичні правила хуків, а й правила, побудовані на аналізі React Compiler.
// eslint.config.js
import reactHooks from 'eslint-plugin-react-hooks';
import { defineConfig } from 'eslint/config';
export default defineConfig([
reactHooks.configs.flat.recommended,
]);
Класичні правила:
rules-of-hooks- хуки лише на верхньому рівні компонентів і власних хуків, не в умовах і циклах;exhaustive-deps- усі значення, використані вuseEffect/useMemo/useCallback, мають бути в залежностях.
Правила компілятора (у конфігурації recommended) ловлять порушення правил React, через які компонент працюватиме неправильно або компілятор його пропустить:
purity- нечисті виклики під час рендеру (Math.random(),Date.now()у тілі компонента);immutability- мутація props, стану чи значень з хуків;refs- читання чи записref.currentпід час рендеру;set-state-in-renderіset-state-in-effect- викликsetStateпрямо в рендері (нескінченний цикл) чи синхронно в ефекті (зайвий рендер; часто стан можна обчислити під час рендеру);static-components- оголошення компонента всередині іншого компонента (він перестворюється щоразу й губить стан);globals- зміна глобальних змінних під час рендеру;preserve-manual-memoization- ручнийuseMemo/useCallback, який компілятор не може зберегти;incompatible-library- бібліотеки з API, несумісним з мемоізацією компілятора;error-boundaries,use-memo,unsupported-syntax,config,gating.
Конфігурація recommended-latest додає експериментальні правила.
Чому це важливо навіть без компілятора: кожне з цих порушень - справжній баг або джерело зайвих рендерів незалежно від того, чи увімкнено компілятор. А з компілятором ESLint показує, які компоненти він пропустить і чому, - ще в редакторі.
Як упроваджувати в старий проєкт:
- увімкнути правила й подивитися кількість порушень - це оцінка, наскільки код готовий до компілятора;
- виправляти поступово, починаючи з
purity,immutability,refs- вони вказують на реальні помилки; - не вимикати правило коментарем без пояснення:
eslint-disableдляexhaustive-deps- найчастіше маскування справжньої проблеми із застарілими значеннями (stale closure).