Skip to main content
interlace
Plugin: react-featuresRules

no-set-state

no-set-state rule

no-set-state rule

Disallow usage of setState to encourage functional components with hooks. This rule is part of eslint-plugin-react-features.

Quick Summary

AspectDetails
SeverityWarning (modernization)
Auto-Fix❌ No (requires component refactor)
CategoryReact
ESLint MCP✅ Optimized for ESLint MCP integration
Best ForProjects migrating to hooks

Rule Details

This rule flags all usages of setState to encourage migration to functional components with the useState hook. Hooks provide a cleaner API for state management.

Why This Matters

IssueImpactSolution
🔄 Verbose syntaxMore boilerplate codeUse useState hook
🐛 Complex this bindingCommon source of bugsHooks avoid this
🔍 Logic reuseHard to share stateful logicCustom hooks enable reuse

Examples

❌ Incorrect

class Counter extends React.Component {
  state = { count: 0 };
  
  increment = () => {
    // BAD: Using setState in class component
    this.setState({ count: this.state.count + 1 });
    
    // Also flagged
    this.setState(prevState => ({
      count: prevState.count + 1
    }));
  };
  
  render() {
    return (
      <button onClick={this.increment}>
        Count: {this.state.count}
      </button>
    );
  }
}

✅ Correct

// GOOD: Functional component with useState
function Counter() {
  const [count, setCount] = useState(0);
  
  const increment = useCallback(() => {
    setCount(c => c + 1);
  }, []);
  
  return (
    <button onClick={increment}>
      Count: {count}
    </button>
  );
}

// GOOD: Complex state with useReducer
function TodoList() {
  const [state, dispatch] = useReducer(todoReducer, initialState);
  
  const addTodo = useCallback((text) => {
    dispatch({ type: 'ADD_TODO', payload: text });
  }, []);
  
  return <TodoItems items={state.todos} onAdd={addTodo} />;
}

Configuration Examples

Basic Usage

{
  rules: {
    'react-features/no-set-state': 'warn'
  }
}

Strict (for new projects)

{
  rules: {
    'react-features/no-set-state': 'error'
  }
}

Further Reading

Known False Negatives

  • An alias of this (const self = this; self.setState(...)) is not read as the component's setState.
  • createReactClass components are not covered; only classes that extend React's Component / PureComponent.

Not reported by design: another object's setState (a store: useStore.setState(...)) and a setState the code defines on a class that is not a React component.

Use this rule

npm install -D oxlint-plugin-react-features
.oxlintrc.json
{  "jsPlugins": ["oxlint-plugin-react-features"],  "rules": {    "react-features/no-set-state": "error"  }}
vite.config.ts
import { defineConfig } from 'vite-plus';export default defineConfig({  lint: {    jsPlugins: ['oxlint-plugin-react-features'],    rules: {      'react-features/no-set-state': 'error',    },  },});

oxlint-plugin-react-features re-exports eslint-plugin-react-features/oxlint: the same rules under the same IDs, and no ESLint install. Why oxlint.

Did this rule catch something? Star the repo to get new CWE coverage as we ship it — or follow the AI-code-security benchmarks behind these rules.