dotCMS / dotCMS/core

task(sdk): Fix React hooks lint violations before upgrading eslint-plugin-react-hooks to v7

Open
#34,891 0 comments 1 reaction 2 assignees View on GitHub

@fmontes is already working on this.

Since Mar 11, 2026.

dotCMS : SDK Team : Falcon Type : Task
Dominant language
Java
Stars
970
Forks
486
Avg merge
3d 33m
Merged PRs (30d)
170

Description

Description

eslint-plugin-react-hooks v7 introduces stricter lint rules (react-hooks/set-state-in-effect, react-hooks/immutability, react-hooks/refs) that cause 11 lint errors across sdk-react and sdk-experiments.

The upgrade from 5.0.0^7.0.1 was attempted in the remove-unnused-libs-exports-imports-enum branch and had to be reverted to unblock CI. These violations need to be resolved before re-attempting the upgrade.

Approach: All violations must be resolved by refactoring to follow React best practices — no eslint-disable suppression. Tests must be added or updated for every refactored hook/component.


sdk-react (7 errors)
File Line(s) Rule Issue
DotCMSBlockEditorRenderer.tsx 91 set-state-in-effect setBlockEditorState() called synchronously in useEffect. Can derive with useMemo.
Texts.tsx 124–125 immutability Mutating mark.attrs directly (setting className, deleting class). Should clone before mutating.
DotCMSEditableText.tsx 50 set-state-in-effect setContent() in useEffect. Can derive state directly.
DotCMSEditableText.tsx 56 set-state-in-effect setInitEditor() in useEffect. Can derive state directly.
useCheckVisibleContent.ts 30 set-state-in-effect setHaveContent() in useLayoutEffect.
useDotCMSShowWhen.ts 39 set-state-in-effect setShow() in useEffect. Can use useMemo.
sdk-experiments (4 errors)
File Line(s) Rule Issue
useExperimentVariant.ts 35, 48, 60 set-state-in-effect setShouldWaitForVariant() called synchronously in useEffect.
memoize.ts 44, 45, 48 refs Accessing/writing ref.current during render in useMemoizedObject.
Acceptance Criteria
Refactoring (one per violation)
  • DotCMSBlockEditorRenderer.tsx — Replace useState + useEffect with useMemo for block validation state
  • Texts.tsx — Clone mark.attrs before mutating (rename classclassName); no direct object mutation
  • DotCMSEditableText.tsx:50 — Derive content state without synchronous setState inside useEffect
  • DotCMSEditableText.tsx:56 — Derive initEditor state without synchronous setState inside useEffect
  • useCheckVisibleContent.ts — Remove synchronous setState from useLayoutEffect
  • useDotCMSShowWhen.ts — Replace useState + useEffect with useMemo
  • useExperimentVariant.ts — Remove synchronous setShouldWaitForVariant() calls from useEffect
  • memoize.ts — Refactor useMemoizedObject to avoid reading/writing ref.current during render
Quality gates
  • All fixes use proper React patterns — no eslint-disable comments for these rules
  • Tests added or updated for each refactored hook: useCheckVisibleContent, useDotCMSShowWhen, useMemoizedObject, useExperimentVariant
  • Tests added or updated for refactored components: DotCMSBlockEditorRenderer, Texts.TextBlock, DotCMSEditableText
  • eslint-plugin-react-hooks upgraded from 5.0.0 to ^7.0.1 in core-web/package.json
  • yarn nx run sdk-react:lint passes with zero errors
  • yarn nx run sdk-experiments:lint passes with zero errors
  • yarn nx run sdk-react:test passes with zero failures
  • yarn nx run sdk-experiments:test passes with zero failures
Priority

Medium

Additional Context

Reproduction:

# In core-web/package.json, change eslint-plugin-react-hooks to "^7.0.1"
yarn install
yarn nx affected -t lint --base=origin/main --exclude='tag:skip:lint'

Key references:

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.