diff --git a/docs/rules/no-unstable-nested-components.md b/docs/rules/no-unstable-nested-components.md
index 7e0abc93d4..01e280fd2f 100644
--- a/docs/rules/no-unstable-nested-components.md
+++ b/docs/rules/no-unstable-nested-components.md
@@ -2,9 +2,9 @@
💼 This rule is enabled in the following [configs](https://github.com/jsx-eslint/eslint-plugin-react#shareable-configurations): `all`.
-Creating components inside components without memoization leads to unstable components. The nested component and all its children are recreated during each re-render. Given stateful children of the nested component will lose their state on each re-render.
+Creating components inside components (nested components) will cause React to throw away the state of those nested components on each re-render of their parent.
-React reconciliation performs element type comparison with [reference equality](https://github.com/facebook/react/blob/v16.13.1/packages/react-reconciler/src/ReactChildFiber.js#L407). The reference to the same element changes on each re-render when defining components inside the render block. This leads to complete recreation of the current node and all its children. As a result the virtual DOM has to do extra unnecessary work and [possible bugs are introduced](https://codepen.io/ariperkkio/pen/vYLodLB).
+React reconciliation performs element type comparison with [reference equality](https://reactjs.org/docs/reconciliation.html#elements-of-different-types). The reference to the same element changes on each re-render when defining components inside the render block. This leads to complete recreation of the current node and all its children. As a result the virtual DOM has to do extra unnecessary work and [possible bugs are introduced](https://codepen.io/ariperkkio/pen/vYLodLB).
## Rule Details
@@ -76,6 +76,20 @@ function Component() {
```jsx
function Component() {
+ return } />;
+}
+```
+
+⚠️ WARNING ⚠️:
+
+Creating nested but memoized components is currently not detected by this rule but should also be avoided.
+If the `useCallback` or `useMemo` hook has no dependency, you can safely move the component definition out of the render function.
+If the hook does have dependencies, you should refactor the code so that you're able to move the component definition out of the render function.
+If you want React to throw away the state of the nested component, use a [`key`](https://reactjs.org/docs/lists-and-keys.html#keys) instead.
+
+```jsx
+function Component() {
+ // No ESLint warning but `MemoizedNestedComponent` should be moved outside of `Component`.
const MemoizedNestedComponent = React.useCallback(() =>
, []);
return (
@@ -86,14 +100,6 @@ function Component() {
}
```
-```jsx
-function Component() {
- return (
- } />
- )
-}
-```
-
By default component creation is allowed inside component props only if prop name starts with `render`. See `allowAsProps` option for disabling this limitation completely.
```jsx
diff --git a/tests/lib/rules/no-unstable-nested-components.js b/tests/lib/rules/no-unstable-nested-components.js
index fd383fb8b5..a27444ebfd 100644
--- a/tests/lib/rules/no-unstable-nested-components.js
+++ b/tests/lib/rules/no-unstable-nested-components.js
@@ -78,6 +78,7 @@ ruleTester.run('no-unstable-nested-components', rule, {
`,
},
{
+ // false-negative.
code: `
function ParentComponent() {
const MemoizedNestedComponent = React.useCallback(() => , []);
@@ -91,6 +92,7 @@ ruleTester.run('no-unstable-nested-components', rule, {
`,
},
{
+ // false-negative.
code: `
function ParentComponent() {
const MemoizedNestedComponent = React.useCallback(
@@ -107,6 +109,7 @@ ruleTester.run('no-unstable-nested-components', rule, {
`,
},
{
+ // false-negative.
code: `
function ParentComponent() {
const MemoizedNestedFunctionComponent = React.useCallback(
@@ -125,6 +128,7 @@ ruleTester.run('no-unstable-nested-components', rule, {
`,
},
{
+ // false-negative.
code: `
function ParentComponent() {
const MemoizedNestedFunctionComponent = React.useCallback(