Включить react-hooks/exhaustive-deps и разобрать устаревшие замыкания
Правило было не задано вовсе: плагин eslint-plugin-react-hooks подключает профиль @microsoft/eslint-config-spfx/lib/profiles/react, но правил из него не включает. Теперь в .eslintrc.js явно заданы rules-of-hooks (error) и exhaustive-deps (warn); сборка проходит с нулём предупреждений. Что реально чинилось, а не затыкалось: - shared/useStableCallback.ts — обёртка с неизменной ссылкой над колбэком-пропом (аналог будущего useEffectEvent). Ссылка стабильна, внутри всегда актуальная версия колбэка, поэтому её можно честно класть в зависимости. - onCodeLoaded во всех forms/*/*View.tsx и *Form.tsx идёт в эффект загрузки через эту обёртку: просто дописать проп в зависимости нельзя — заявка перезапрашивалась бы на каждый рендер родителя. - useRequestSubmit: run стабилизирован (useCallback + savingRef вместо чтения состояния), возвращаемый объект мемоизирован. Формы берут из него стабильный setError и указывают в зависимостях его, а не submit целиком. - shared/usePersistedQuery.ts (useRoutedQuery) — было устаревшее замыкание: эффект навсегда запоминал первую версию onQueryChange, а та замкнута на route на момент монтирования, то есть набранный запрос мог уехать в маршрут чужого раздела. Теперь зовётся актуальная версия. - propertyPane/DebugUserField.tsx — то же самое с onResolved. - Формы: в эффект "новая заявка по умолчанию на себя" дописан context (единственный экземпляр на жизнь веб-части, лишних перезапусков не даёт), в ReferralForm ещё и мемоизированный approval. - RequestsTableView: dataKey в зависимости (он и так выводится из view/ statusFilter/debouncedQuery, которые там уже есть). Осознанные отступления оставлены с объяснением ПОЧЕМУ: useMatrixEditor (момент перечитывания матрицы задаёт вызывающий через reloadKey), companiesFieldValue в RecruitingHire/RecruitingSelection. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -290,6 +290,22 @@ module.exports = {
|
||||
// Rationale to disable: !!{}
|
||||
'no-extra-boolean-cast': 0,
|
||||
// ====================================================================
|
||||
// eslint-plugin-react-hooks (плагин подключён профилем
|
||||
// @microsoft/eslint-config-spfx/lib/profiles/react, но правил он не задаёт)
|
||||
// ====================================================================
|
||||
// RATIONALE: Хуки нельзя звать условно/в циклах — иначе React
|
||||
// перепутает состояние между рендерами.
|
||||
'react-hooks/rules-of-hooks': 2,
|
||||
// RATIONALE: Неполный массив зависимостей useEffect/useCallback/
|
||||
// useMemo — это устаревшее замыкание: эффект продолжает
|
||||
// видеть старые пропсы и state. Держим предупреждением:
|
||||
// там, где отступление осознанное (например, эффект
|
||||
// должен сработать только на смену id, а не на каждое
|
||||
// изменение колбэка), рядом стоит
|
||||
// // eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
// с объяснением причины.
|
||||
'react-hooks/exhaustive-deps': 1,
|
||||
// ====================================================================
|
||||
// @microsoft/eslint-plugin-spfx
|
||||
// ====================================================================
|
||||
'@microsoft/spfx/no-require-ensure': 2,
|
||||
|
||||
Reference in New Issue
Block a user