Problem Description
This rule validates that components are static, not recreated every render. Components that are recreated dynamically can reset state and trigger excessive re-rendering.
Components defined inside other components are recreated on every render. React sees each as a brand new component type, unmounting the old one and mounting the new one, destroying all state and DOM nodes in the process.
This is a common pitfall for React developers, especially beginners, who might define components inside other components to access local variables, not realizing the performance and state loss implications.
Alternative Solutions
Rule Documentation Template
Rule Details
This rule enforces that React components are defined statically, outside of other components. When a component is defined inside another component, it gets recreated on every render. React treats each recreation as a brand new component type, causing the old component to unmount and the new one to mount, which destroys all state and DOM nodes.
This pattern is problematic because:
- State is lost on every parent re-render
- Performance is degraded due to unnecessary unmounting/remounting
- It can cause subtle bugs that are hard to track down
If you find yourself wanting to define components inside other components to access local variables, that's a sign you should be passing props instead. This makes components more reusable and testable.
Common Violations
Invalid
// ❌ Bad: Component defined inside another component causes state reset on every render
function Parent() {
const [count, setCount] = useState(0);
// This component is recreated on every Parent render
function Child() {
return <div>Child content</div>;
}
return (
<div>
<button onClick={() => setCount(c => c + 1)}>Count: {count}</button>
<Child />
</div>
);
}
// ❌ Bad: Arrow function component defined inside render
function Parent() {
const localData = fetchData();
const ChildComponent = () => {
return <div>{localData}</div>;
};
return <ChildComponent />;
}
Valid
// ✅ Good: Component defined outside, receives data via props
function Child({ data }) {
return <div>{data}</div>;
}
function Parent() {
const [count, setCount] = useState(0);
const localData = fetchData();
return (
<div>
<button onClick={() => setCount(c => c + 1)}>Count: {count}</button>
<Child data={localData} />
</div>
);
}
// ✅ Good: Using hooks to share logic instead of nested components
function useLocalData() {
return fetchData();
}
function Child() {
const data = useLocalData();
return <div>{data}</div>;
}
function Parent() {
const [count, setCount] = useState(0);
return (
<div>
<button onClick={() => setCount(c => c + 1)}>Count: {count}</button>
<Child />
</div>
);
}
Troubleshooting
Why is this pattern problematic?
When you define a component inside another component, JavaScript creates a new function on every render. React uses the function reference to identify component types. Since the function reference changes on every render, React thinks it's a completely different component type and performs a full unmount/remount cycle, destroying all internal state and DOM.
What are the alternatives?
- Pass data via props: Move the child component outside the parent and pass the needed data as props.
- Use custom hooks: If you need to share logic, extract it into a custom hook instead of a nested component.
- Component composition: Structure your components so that data flows down through props rather than being captured in closures.
Resources
- Rule Source: (to be added after implementation)
Further Reading
Evaluation Checklist
Problem Description
This rule validates that components are static, not recreated every render. Components that are recreated dynamically can reset state and trigger excessive re-rendering.
Components defined inside other components are recreated on every render. React sees each as a brand new component type, unmounting the old one and mounting the new one, destroying all state and DOM nodes in the process.
This is a common pitfall for React developers, especially beginners, who might define components inside other components to access local variables, not realizing the performance and state loss implications.
Alternative Solutions
Rule Documentation Template
Rule Details
This rule enforces that React components are defined statically, outside of other components. When a component is defined inside another component, it gets recreated on every render. React treats each recreation as a brand new component type, causing the old component to unmount and the new one to mount, which destroys all state and DOM nodes.
This pattern is problematic because:
If you find yourself wanting to define components inside other components to access local variables, that's a sign you should be passing props instead. This makes components more reusable and testable.
Common Violations
Invalid
Valid
Troubleshooting
Why is this pattern problematic?
When you define a component inside another component, JavaScript creates a new function on every render. React uses the function reference to identify component types. Since the function reference changes on every render, React thinks it's a completely different component type and performs a full unmount/remount cycle, destroying all internal state and DOM.
What are the alternatives?
Resources
Further Reading
Evaluation Checklist