Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion src/components/Layout/Sidebar/SidebarLink.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ interface SidebarLinkProps {
selected?: boolean;
title: string;
level: number;
version?: 'canary' | 'major' | 'experimental';
version?: 'canary' | 'major' | 'experimental' | 'rc';
icon?: React.ReactNode;
isExpanded?: boolean;
hideArrow?: boolean;
Expand Down Expand Up @@ -102,6 +102,12 @@ export function SidebarLink({
className="ms-1 text-gray-30 dark:text-gray-60 inline-block w-3.5 h-3.5 align-[-3px]"
/>
)}
{version === 'rc' && (
<IconCanary
title=" - This feature is available in the latest RC version"
className="ms-1 text-gray-30 dark:text-gray-60 inline-block w-3.5 h-3.5 align-[-3px]"
/>
)}
</div>

{isExpanded != null && !hideArrow && (
Expand Down
10 changes: 10 additions & 0 deletions src/components/MDX/ExpandableCallout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ type CalloutVariants =
| 'wip'
| 'canary'
| 'experimental'
| 'rc'
| 'major'
| 'rsc';

Expand All @@ -50,6 +51,15 @@ const variantMap = {
overlayGradient:
'linear-gradient(rgba(245, 249, 248, 0), rgba(245, 249, 248, 1)',
},
rc: {
title: 'RC',
Icon: IconCanary,
containerClasses:
'bg-gray-5 dark:bg-gray-60 dark:bg-opacity-20 text-primary dark:text-primary-dark text-lg',
textColor: 'text-gray-60 dark:text-gray-30',
overlayGradient:
'linear-gradient(rgba(245, 249, 248, 0), rgba(245, 249, 248, 1)',
},
canary: {
title: 'Canary',
Icon: IconCanary,
Expand Down
5 changes: 5 additions & 0 deletions src/components/MDX/MDXComponents.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,10 @@ const Canary = ({children}: {children: React.ReactNode}) => (
<ExpandableCallout type="canary">{children}</ExpandableCallout>
);

const RC = ({children}: {children: React.ReactNode}) => (
<ExpandableCallout type="rc">{children}</ExpandableCallout>
);

const Experimental = ({children}: {children: React.ReactNode}) => (
<ExpandableCallout type="experimental">{children}</ExpandableCallout>
);
Expand Down Expand Up @@ -533,6 +537,7 @@ export const MDXComponents = {
Math,
MathI,
Note,
RC,
Canary,
Experimental,
ExperimentalBadge,
Expand Down
8 changes: 7 additions & 1 deletion src/components/PageHeading.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import {IconExperimental} from './Icon/IconExperimental';

interface PageHeadingProps {
title: string;
version?: 'experimental' | 'canary';
version?: 'experimental' | 'canary' | 'rc';
experimental?: boolean;
status?: string;
description?: string;
Expand All @@ -46,6 +46,12 @@ function PageHeading({
className="ms-4 mt-1 text-gray-50 dark:text-gray-40 inline-block w-6 h-6 align-[-1px]"
/>
)}
{version === 'rc' && (
<IconCanary
title=" - This feature is available in the latest RC version"
className="ms-4 mt-1 text-gray-50 dark:text-gray-40 inline-block w-6 h-6 align-[-1px]"
/>
)}
{version === 'experimental' && (
<IconExperimental
title=" - This feature is available in the latest Experimental version of React"
Expand Down
20 changes: 17 additions & 3 deletions src/content/reference/eslint-plugin-react-hooks/index.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
---
title: eslint-plugin-react-hooks
version: rc
---

<Intro>
Expand All @@ -8,6 +9,14 @@ title: eslint-plugin-react-hooks

</Intro>

<RC>

These docs include rules available in the RC version of `eslint-plugin-react-hooks`.

You can try them by upgrading the lint plugin [to the most recent RC version](/learn/react-compiler/installation#eslint-integration).

</RC>

This plugin helps you catch violations of React's rules at build time, ensuring your components and hooks follow React's rules for correctness and performance. The lints cover both fundamental React patterns (exhaustive-deps and rules-of-hooks) and issues flagged by React Compiler. React Compiler diagnostics are automatically surfaced by this ESLint plugin, and can be used even if your app hasn't adopted the compiler yet.

<Note>
Expand All @@ -18,18 +27,23 @@ What this means for linting, is that you don’t need to fix all violations imme

## Available Lints {/*available-lints*/}

* [`component-hook-factories`](/reference/eslint-plugin-react-hooks/lints/component-hook-factories) - Validates against higher order functions defining nested components or hooks
These rules are available in the stable version of `eslint-plugin-react-hooks`:

* [`exhaustive-deps`](/reference/eslint-plugin-react-hooks/lints/exhaustive-deps) - Validates that dependency arrays for React hooks contain all necessary dependencies
* [`rules-of-hooks`](/reference/eslint-plugin-react-hooks/lints/rules-of-hooks) - Validates that components and hooks follow the Rules of Hooks

These rules are available in the RC version of `eslint-plugin-react-hooks`:

* [`component-hook-factories`](/reference/eslint-plugin-react-hooks/lints/component-hook-factories) - Validates higher order functions defining nested components or hooks
* [`config`](/reference/eslint-plugin-react-hooks/lints/config) - Validates the compiler configuration options
* [`error-boundaries`](/reference/eslint-plugin-react-hooks/lints/error-boundaries) - Validates usage of Error Boundaries instead of try/catch for child errors
* [`exhaustive-deps`](/reference/eslint-plugin-react-hooks/lints/exhaustive-deps) - Validates that dependency arrays for React hooks contain all necessary dependencies
* [`gating`](/reference/eslint-plugin-react-hooks/lints/gating) - Validates configuration of gating mode
* [`globals`](/reference/eslint-plugin-react-hooks/lints/globals) - Validates against assignment/mutation of globals during render
* [`immutability`](/reference/eslint-plugin-react-hooks/lints/immutability) - Validates against mutating props, state, and other immutable values
* [`incompatible-library`](/reference/eslint-plugin-react-hooks/lints/incompatible-library) - Validates against usage of libraries which are incompatible with memoization
* [`preserve-manual-memoization`](/reference/eslint-plugin-react-hooks/lints/preserve-manual-memoization) - Validates that existing manual memoization is preserved by the compiler
* [`purity`](/reference/eslint-plugin-react-hooks/lints/purity) - Validates that components/hooks are pure by checking known-impure functions
* [`refs`](/reference/eslint-plugin-react-hooks/lints/refs) - Validates correct usage of refs, not reading/writing during render
* [`rules-of-hooks`](/reference/eslint-plugin-react-hooks/lints/rules-of-hooks) - Validates that components and hooks follow the Rules of Hooks
* [`set-state-in-effect`](/reference/eslint-plugin-react-hooks/lints/set-state-in-effect) - Validates against calling setState synchronously in an effect
* [`set-state-in-render`](/reference/eslint-plugin-react-hooks/lints/set-state-in-render) - Validates against setting state during render
* [`static-components`](/reference/eslint-plugin-react-hooks/lints/static-components) - Validates that components are static, not recreated every render
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
---
title: component-hook-factories
version: rc
---

<Intro>
Expand All @@ -8,6 +9,14 @@ Validates against higher order functions defining nested components or hooks. Co

</Intro>

<RC>

This rule is available in the RC version of `eslint-plugin-react-hooks`.

You can try it by upgrading the lint plugin [to the most recent RC version](/learn/react-compiler/installation#eslint-integration).

</RC>

## Rule Details {/*rule-details*/}

Defining components or hooks inside other functions creates new instances on every call. React treats each as a completely different component, destroying and recreating the entire component tree, losing all state, and causing performance problems.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
---
title: config
version: rc
---

<Intro>
Expand All @@ -8,6 +9,14 @@ Validates the compiler [configuration options](/reference/react-compiler/configu

</Intro>

<RC>

This rule is available in the RC version of `eslint-plugin-react-hooks`.

You can try it by upgrading the lint plugin [to the most recent RC version](/learn/react-compiler/installation#eslint-integration).

</RC>

## Rule Details {/*rule-details*/}

React Compiler accepts various [configuration options](/reference/react-compiler/configuration) to control its behavior. This rule validates that your configuration uses correct option names and value types, preventing silent failures from typos or incorrect settings.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
---
title: error-boundaries
version: rc
---

<Intro>
Expand All @@ -8,6 +9,14 @@ Validates usage of Error Boundaries instead of try/catch for errors in child com

</Intro>

<RC>

This rule is available in the RC version of `eslint-plugin-react-hooks`.

You can try it by upgrading the lint plugin [to the most recent RC version](/learn/react-compiler/installation#eslint-integration).

</RC>

## Rule Details {/*rule-details*/}

Try/catch blocks can't catch errors that happen during React's rendering process. Errors thrown in rendering methods or hooks bubble up through the component tree. Only [Error Boundaries](/reference/react/Component#catching-rendering-errors-with-an-error-boundary) can catch these errors.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
---
title: gating
version: rc
---

<Intro>
Expand All @@ -8,6 +9,14 @@ Validates configuration of [gating mode](/reference/react-compiler/gating).

</Intro>

<RC>

This rule is available in the RC version of `eslint-plugin-react-hooks`.

You can try it by upgrading the lint plugin [to the most recent RC version](/learn/react-compiler/installation#eslint-integration).

</RC>

## Rule Details {/*rule-details*/}

Gating mode lets you gradually adopt React Compiler by marking specific components for optimization. This rule ensures your gating configuration is valid so the compiler knows which components to process.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
---
title: globals
version: rc
---

<Intro>
Expand All @@ -8,6 +9,14 @@ Validates against assignment/mutation of globals during render, part of ensuring

</Intro>

<RC>

This rule is available in the RC version of `eslint-plugin-react-hooks`.

You can try it by upgrading the lint plugin [to the most recent RC version](/learn/react-compiler/installation#eslint-integration).

</RC>

## Rule Details {/*rule-details*/}

Global variables exist outside React's control. When you modify them during render, you break React's assumption that rendering is pure. This can cause components to behave differently in development vs production, break Fast Refresh, and make your app impossible to optimize with features like React Compiler.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
---
title: immutability
version: rc
---

<Intro>
Expand All @@ -8,6 +9,14 @@ Validates against mutating props, state, and other values that [are immutable](/

</Intro>

<RC>

This rule is available in the RC version of `eslint-plugin-react-hooks`.

You can try it by upgrading the lint plugin [to the most recent RC version](/learn/react-compiler/installation#eslint-integration).

</RC>

## Rule Details {/*rule-details*/}

A component’s props and state are immutable snapshots. Never mutate them directly. Instead, pass new props down, and use the setter function from `useState`.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
---
title: incompatible-library
version: rc
---

<Intro>
Expand All @@ -8,6 +9,14 @@ Validates against usage of libraries which are incompatible with memoization (ma

</Intro>

<RC>

This rule is available in the RC version of `eslint-plugin-react-hooks`.

You can try it by upgrading the lint plugin [to the most recent RC version](/learn/react-compiler/installation#eslint-integration).

</RC>

<Note>

These libraries were designed before React's memoization rules were fully documented. They made the correct choices at the time to optimize for ergonomic ways to keep components just the right amount of reactive as app state changes. While these legacy patterns worked, we have since discovered that it's incompatible with React's programming model. We will continue working with library authors to migrate these libraries to use patterns that follow the Rules of React.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
---
title: preserve-manual-memoization
version: rc
---

<Intro>
Expand All @@ -8,6 +9,14 @@ Validates that existing manual memoization is preserved by the compiler. React C

</Intro>

<RC>

This rule is available in the RC version of `eslint-plugin-react-hooks`.

You can try it by upgrading the lint plugin [to the most recent RC version](/learn/react-compiler/installation#eslint-integration).

</RC>

## Rule Details {/*rule-details*/}

React Compiler preserves your existing `useMemo`, `useCallback`, and `React.memo` calls. If you've manually memoized something, the compiler assumes you had a good reason and won't remove it. However, incomplete dependencies prevent the compiler from understanding your code's data flow and applying further optimizations.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
---
title: purity
version: rc
---

<Intro>
Expand All @@ -8,6 +9,14 @@ Validates that [components/hooks are pure](/reference/rules/components-and-hooks

</Intro>

<RC>

This rule is available in the RC version of `eslint-plugin-react-hooks`.

You can try it by upgrading the lint plugin [to the most recent RC version](/learn/react-compiler/installation#eslint-integration).

</RC>

## Rule Details {/*rule-details*/}

React components must be pure functions - given the same props, they should always return the same JSX. When components use functions like `Math.random()` or `Date.now()` during render, they produce different output each time, breaking React's assumptions and causing bugs like hydration mismatches, incorrect memoization, and unpredictable behavior.
Expand Down
9 changes: 9 additions & 0 deletions src/content/reference/eslint-plugin-react-hooks/lints/refs.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
---
title: refs
version: rc
---

<Intro>
Expand All @@ -8,6 +9,14 @@ Validates correct usage of refs, not reading/writing during render. See the "pit

</Intro>

<RC>

This rule is available in the RC version of `eslint-plugin-react-hooks`.

You can try it by upgrading the lint plugin [to the most recent RC version](/learn/react-compiler/installation#eslint-integration).

</RC>

## Rule Details {/*rule-details*/}

Refs hold values that aren't used for rendering. Unlike state, changing a ref doesn't trigger a re-render. Reading or writing `ref.current` during render breaks React's expectations. Refs might not be initialized when you try to read them, and their values can be stale or inconsistent.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
---
title: set-state-in-effect
version: rc
---

<Intro>
Expand All @@ -8,6 +9,14 @@ Validates against calling setState synchronously in an effect, which can lead to

</Intro>

<RC>

This rule is available in the RC version of `eslint-plugin-react-hooks`.

You can try it by upgrading the lint plugin [to the most recent RC version](/learn/react-compiler/installation#eslint-integration).

</RC>

## Rule Details {/*rule-details*/}

Setting state immediately inside an effect forces React to restart the entire render cycle. When you update state in an effect, React must re-render your component, apply changes to the DOM, and then run effects again. This creates an extra render pass that could have been avoided by transforming data directly during render or deriving state from props. Transform data at the top level of your component instead. This code will naturally re-run when props or state change without triggering additional render cycles.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
---
title: set-state-in-render
version: rc
---

<Intro>
Expand All @@ -8,6 +9,14 @@ Validates against setting state during render, which can trigger additional rend

</Intro>

<RC>

This rule is available in the RC version of `eslint-plugin-react-hooks`.

You can try it by upgrading the lint plugin [to the most recent RC version](/learn/react-compiler/installation#eslint-integration).

</RC>

## Rule Details {/*rule-details*/}

Calling `setState` during render triggers another render before the current one finishes. This creates an infinite loop that crashes your app.
Expand Down
Loading