Skip to content

implement no-mutating-reducer-state rule#491

Merged
rayhanadev merged 8 commits into
mainfrom
discovery/implement-no-mutating-reducer-state
May 26, 2026
Merged

implement no-mutating-reducer-state rule#491
rayhanadev merged 8 commits into
mainfrom
discovery/implement-no-mutating-reducer-state

Conversation

@rayhanadev

@rayhanadev rayhanadev commented May 26, 2026

Copy link
Copy Markdown
Member

Why

Catches reducers that mutate the current state object and then return that same object.

React compares reducer state by reference. If a reducer changes the old object in place and returns it, React can treat the update as unchanged. That can skip rerenders or leave memoized consumers with stale data.

Before, this reducer mutates state.items and returns the same state object, so the rule reports it:

import { useReducer } from "react";

function reducer(state, action) {
  if (action.type === "add") {
    state.items.push(action.item);
    return state;
  }

  return state;
}

useReducer(reducer, { items: [] });

After, the reducer returns a new state object, so the rule does not report it:

import { useReducer } from "react";

function reducer(state, action) {
  if (action.type === "add") {
    return {
      ...state,
      items: [...state.items, action.item],
    };
  }

  return state;
}

useReducer(reducer, { items: [] });

What changed

  • Added no-mutating-reducer-state under State & Effects.
  • Detects real React useReducer calls and same-file reducer functions.
  • Tracks aliases to the original state, like const next = state.
  • Reports common mutations when the same state reference can be returned.
  • Allows safe patterns like clone-first updates, no-op return state, Immer-style wrappers, and non-React useReducer calls.
  • Added tests for valid bugs, false-positive guards, and eval-derived edge cases.

Test plan

pnpm exec vp test run packages/oxlint-plugin-react-doctor/src/plugin/rules/state-and-effects/no-mutating-reducer-state.test.ts
pnpm --filter oxlint-plugin-react-doctor typecheck
pnpm lint

Co-authored-by: Cursor <cursoragent@cursor.com>
Copilot AI review requested due to automatic review settings May 26, 2026 03:41
@reactreview

reactreview Bot commented May 26, 2026

Copy link
Copy Markdown

No new issues

Reviewed by reactreview for commit 1c6553e. Configure here.

This comment was marked as resolved.

@rayhanadev rayhanadev requested a review from aidenybai May 26, 2026 03:44
@rayhanadev

Copy link
Copy Markdown
Member Author

bugbot run

cursor[bot]

This comment was marked as resolved.

rayhanadev and others added 2 commits May 25, 2026 21:07
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
@rayhanadev

Copy link
Copy Markdown
Member Author

bugbot run

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ Bugbot reviewed your changes and found no new issues!

Comment @cursor review or bugbot run to trigger another review on this PR

Reviewed by Cursor Bugbot for commit ccaaa82. Configure here.

Co-authored-by: Cursor <cursoragent@cursor.com>

@devin-ai-integration devin-ai-integration Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Devin Review found 1 potential issue.

View 4 additional findings in Devin Review.

Open in Devin Review

rayhanadev and others added 4 commits May 25, 2026 21:53
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
@rayhanadev rayhanadev requested a review from aidenybai May 26, 2026 05:11
@rayhanadev rayhanadev merged commit 4b5d40e into main May 26, 2026
12 checks passed
@rayhanadev rayhanadev deleted the discovery/implement-no-mutating-reducer-state branch May 26, 2026 05:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants