logo by @sawaratsuki1004
React
v19.2
Learn
Reference
Community
Blog

Is this page useful?

في هذه الصفحة

  • Overview
  • Rule Details
  • Common Violations
  • Invalid
  • Valid
  • Troubleshooting
  • I want to fetch data based on some condition
  • I need different state for different scenarios
  • Options

    react@19.2

  • نظرة عامة
  • Hooks
    • useActionState
    • useCallback
    • useContext
    • useDebugValue
    • useDeferredValue
    • useEffect
    • useEffectEvent
    • useId
    • useImperativeHandle
    • useInsertionEffect
    • useLayoutEffect
    • useMemo
    • useOptimistic
    • useReducer
    • useRef
    • useState
    • useSyncExternalStore
    • useTransition
  • المكونات
    • <Fragment> (<>)
    • <Profiler>
    • <StrictMode>
    • <Suspense>
    • <Activity>
    • <ViewTransition> - This feature is available in the latest Canary version of React
  • APIs
    • act
    • addTransitionType - This feature is available in the latest Canary version of React
    • cache
    • cacheSignal
    • captureOwnerStack
    • createContext
    • lazy
    • memo
    • startTransition
    • use
    • experimental_taintObjectReference - This feature is available in the latest Experimental version of React
    • experimental_taintUniqueValue - This feature is available in the latest Experimental version of React
  • react-dom@19.2

  • Hooks
    • useFormStatus
  • المكونات (Components)
    • Common (e.g. <div>)
    • <form>
    • <input>
    • <option>
    • <progress>
    • <select>
    • <textarea>
    • <link>
    • <meta>
    • <script>
    • <style>
    • <title>
  • APIs
    • createPortal
    • flushSync
    • preconnect
    • prefetchDNS
    • preinit
    • preinitModule
    • preload
    • preloadModule
  • Client APIs
    • createRoot
    • hydrateRoot
  • Server APIs
    • renderToPipeableStream
    • renderToReadableStream
    • renderToStaticMarkup
    • renderToString
    • resume
    • resumeToPipeableStream
  • Static APIs
    • prerender
    • prerenderToNodeStream
    • resumeAndPrerender
    • resumeAndPrerenderToNodeStream
  • React Compiler

  • الإعدادات (Configuration)
    • compilationMode
    • gating
    • logger
    • panicThreshold
    • target
  • Directives
    • "use memo"
    • "use no memo"
  • تصريف المكتبات (Compiling Libraries)
  • React DevTools

  • React Performance tracks
  • eslint-plugin-react-hooks

  • Lints
    • exhaustive-deps
    • rules-of-hooks
    • component-hook-factories
    • config
    • error-boundaries
    • gating
    • globals
    • immutability
    • incompatible-library
    • preserve-manual-memoization
    • purity
    • refs
    • set-state-in-effect
    • set-state-in-render
    • static-components
    • unsupported-syntax
    • use-memo
  • قواعد React (Rules of React)

  • نظرة عامة (Overview)
    • Components و Hooks يجب أن تكون Pure
    • React تستدعي Components و Hooks
    • قواعد Hooks
  • React Server Components

  • Server Components
  • Server Functions
  • Directives
    • 'use client'
    • 'use server'
  • Legacy APIs

  • Legacy React APIs
    • Children
    • cloneElement
    • Component
    • createElement
    • createRef
    • forwardRef
    • isValidElement
    • PureComponent
مرجع API
Lints

rules-of-hooks

Validates that components and hooks follow the Rules of Hooks.

Rule Details

React relies on the order in which hooks are called to correctly preserve state between renders. Each time your component renders, React expects the exact same hooks to be called in the exact same order. When hooks are called conditionally or in loops, React loses track of which state corresponds to which hook call, leading to bugs like state mismatches and “Rendered fewer/more hooks than expected” errors.

Common Violations

These patterns violate the Rules of Hooks:

  • Hooks in conditions (if/else, ternary, &&/||)
  • Hooks in loops (for, while, do-while)
  • Hooks after early returns
  • Hooks in callbacks/event handlers
  • Hooks in async functions
  • Hooks in class methods
  • Hooks at module level

ملاحظة

use hook

The use hook is different from other React hooks. You can call it conditionally and in loops:

// ✅ `use` can be conditional if (shouldFetch) { const data = use(fetchPromise); } // ✅ `use` can be in loops for (const promise of promises) { results.push(use(promise)); }

However, use still has restrictions:

  • Can’t be wrapped in try/catch
  • Must be called inside a component or hook

Learn more: use API Reference

Invalid

Examples of incorrect code for this rule:

// ❌ Hook in condition if (isLoggedIn) { const [user, setUser] = useState(null); } // ❌ Hook after early return if (!data) return <Loading />; const [processed, setProcessed] = useState(data); // ❌ Hook in callback <button onClick={() => { const [clicked, setClicked] = useState(false); }}/> // ❌ `use` in try/catch try { const data = use(promise); } catch (e) { // error handling } // ❌ Hook at module level const globalState = useState(0); // Outside component

Valid

Examples of correct code for this rule:

function Component({ isSpecial, shouldFetch, fetchPromise }) { // ✅ Hooks at top level const [count, setCount] = useState(0); const [name, setName] = useState(''); if (!isSpecial) { return null; } if (shouldFetch) { // ✅ `use` can be conditional const data = use(fetchPromise); return <div>{data}</div>; } return <div>{name}: {count}</div>; }

Troubleshooting

I want to fetch data based on some condition

You’re trying to conditionally call useEffect:

// ❌ Conditional hook if (isLoggedIn) { useEffect(() => { fetchUserData(); }, []); }

Call the hook unconditionally, check condition inside:

// ✅ Condition inside hook useEffect(() => { if (isLoggedIn) { fetchUserData(); } }, [isLoggedIn]);

ملاحظة

There are better ways to fetch data rather than in a useEffect. Consider using React Query, useSWR, or React Router 6.4+ for data fetching. These solutions handle deduplicating requests, caching responses, and avoiding network waterfalls.

Learn more: Fetching Data

I need different state for different scenarios

You’re trying to conditionally initialize state:

// ❌ Conditional state if (userType === 'admin') { const [permissions, setPermissions] = useState(adminPerms); } else { const [permissions, setPermissions] = useState(userPerms); }

Always call useState, conditionally set the initial value:

// ✅ Conditional initial value const [permissions, setPermissions] = useState( userType === 'admin' ? adminPerms : userPerms );

Options

You can configure custom effect hooks using shared ESLint settings (available in eslint-plugin-react-hooks 6.1.1 and later):

{ "settings": { "react-hooks": { "additionalEffectHooks": "(useMyEffect|useCustomEffect)" } } }

  • additionalEffectHooks: Regex pattern matching custom hooks that should be treated as effects. This allows useEffectEvent and similar event functions to be called from your custom effect hooks.

This shared configuration is used by both rules-of-hooks and exhaustive-deps rules, ensuring consistent behavior across all hook-related linting.

السابقexhaustive-deps
التاليcomponent-hook-factories

Copyright © Meta Platforms, Inc
no uwu plz
uwu?
Logo by@sawaratsuki1004
تعلم React
بداية سريعة
التثبيت
وصف واجهة المستخدم (UI)
إضافة التفاعلية
إدارة State
مخارج الطوارئ
مرجع API
React APIs
React DOM APIs
المجتمع
ميثاق السلوك
تعرف على الفريق
المساهمون في التوثيق
شكر وتقدير
المزيد
المدونة
React Native
الخصوصية
الشروط
// ✅ `use` can be conditional
if (shouldFetch) {
const data = use(fetchPromise);
}

// ✅ `use` can be in loops
for (const promise of promises) {
results.push(use(promise));
}
// ❌ Hook in condition
if (isLoggedIn) {
const [user, setUser] = useState(null);
}

// ❌ Hook after early return
if (!data) return <Loading />;
const [processed, setProcessed] = useState(data);

// ❌ Hook in callback
<button onClick={() => {
const [clicked, setClicked] = useState(false);
}}/>

// ❌ `use` in try/catch
try {
const data = use(promise);
} catch (e) {
// error handling
}

// ❌ Hook at module level
const globalState = useState(0); // Outside component
function Component({ isSpecial, shouldFetch, fetchPromise }) {
// ✅ Hooks at top level
const [count, setCount] = useState(0);
const [name, setName] = useState('');

if (!isSpecial) {
return null;
}

if (shouldFetch) {
// ✅ `use` can be conditional
const data = use(fetchPromise);
return <div>{data}</div>;
}

return <div>{name}: {count}</div>;
}
// ❌ Conditional hook
if (isLoggedIn) {
useEffect(() => {
fetchUserData();
}, []);
}
// ✅ Condition inside hook
useEffect(() => {
if (isLoggedIn) {
fetchUserData();
}
}, [isLoggedIn]);
// ❌ Conditional state
if (userType === 'admin') {
const [permissions, setPermissions] = useState(adminPerms);
} else {
const [permissions, setPermissions] = useState(userPerms);
}
// ✅ Conditional initial value
const [permissions, setPermissions] = useState(
userType === 'admin' ? adminPerms : userPerms
);
{
"settings": {
"react-hooks": {
"additionalEffectHooks": "(useMyEffect|useCustomEffect)"
}
}
}