Skip to main content
ESLint Interlace
Plugin: react-featuresRules

react-class-to-hooks

react-class-to-hooks rule

Keywords: React, hooks, migration, ESLint rule, class components, functional components, React modernization, auto-fix, LLM-optimized, React migration

Suggest migrating React class components to hooks with detailed migration path. This rule is part of eslint-plugin-react-features and provides LLM-optimized error messages with fix suggestions.

💡 Provides suggestions | 🔧 Automatically fixable

Quick Summary

AspectDetails
SeverityWarning (migration guidance)
Auto-Fix✅ Yes (suggests hooks migration)
CategoryReact / Migration
ESLint MCP✅ Optimized for ESLint MCP integration
Best ForReact projects migrating from class to functional components

Rule Details

Identifies React class components that can be migrated to functional components with hooks, providing complexity analysis and migration guidance.

Configuration

OptionTypeDefaultDescription
ignorePureRenderComponentsbooleanfalseIgnore PureComponent classes
allowComplexLifecyclebooleanfalseAllow complex lifecycle methods without warnings

Examples

❌ Class Component

class UserProfile extends React.Component<Props, State> {
  state = {
    loading: false,
    data: null
  };
  
  componentDidMount() {
    this.fetchData();
  }
  
  fetchData = async () => {
    this.setState({ loading: true });
    const data = await api.getUser(this.props.userId);
    this.setState({ data, loading: false });
  };
  
  render() {
    const { loading, data } = this.state;
    return loading ? <Spinner /> : <div>{data?.name}</div>;
  }
}

✅ Functional Component with Hooks

function UserProfile({ userId }: Props) {
  const [loading, setLoading] = useState(false);
  const [data, setData] = useState<User | null>(null);
  
  useEffect(() => {
    async function fetchData() {
      setLoading(true);
      const userData = await api.getUser(userId);
      setData(userData);
      setLoading(false);
    }
    fetchData();
  }, [userId]);
  
  return loading ? <Spinner /> : <div>{data?.name}</div>;
}

Configuration Examples

{
  rules: {
    'react-features/react-class-to-hooks': ['warn', {
      ignorePureRenderComponents: false,
      allowComplexLifecycle: false
    }]
  }
}

Lifecycle Method Mapping

Class LifecycleHook Equivalent
componentDidMountuseEffect(() => {}, [])
componentDidUpdateuseEffect(() => {}, [deps])
componentWillUnmountuseEffect(() => () => {}, [])
shouldComponentUpdateReact.memo()
getDerivedStateFromPropsuseState + useEffect

Comparison with Alternatives

Featurereact-class-to-hookseslint-plugin-react-hookscodemods
Class Detection✅ Yes❌ No✅ Yes
Migration Suggestions✅ Yes❌ No⚠️ Automated only
Auto-Fix✅ Yes❌ No✅ Yes
LLM-Optimized✅ Yes❌ No❌ No
ESLint MCP✅ Optimized❌ No❌ No
Complexity Analysis✅ Yes❌ No❌ No

Further Reading

Known False Negatives

The following patterns are not detected due to static analysis limitations:

Dynamic Variable References

Why: Static analysis cannot trace values stored in variables or passed through function parameters.

// ❌ NOT DETECTED - Prop from variable
const propValue = computedValue;
<Component prop={propValue} /> // Computation not analyzed

Mitigation: Implement runtime validation and review code manually. Consider using TypeScript branded types for validated inputs.

Imported Values

Why: When values come from imports, the rule cannot analyze their origin or construction.

// ❌ NOT DETECTED - Value from import
import { getValue } from './helpers';
processValue(getValue()); // Cross-file not tracked

Mitigation: Ensure imported values follow the same constraints. Use TypeScript for type safety.