Rules Hub
Coding Rules Library
Rule priority, scope & exceptions
Use this to align rules with the senior-level structure (P0/P1/P2, scope, exceptions/tradeoffs).
Do not define React components inside other components
Inline component definitions create new component identities and can cause remounts and lost state.
Bad example
| 1 | import { useState } from "react"; |
| 2 |
|
| 3 | export function Form() { |
| 4 | const [value, setValue] = useState(""); |
| 5 |
|
| 6 | function Field() { |
| 7 | // This component is redefined each render. |
| 8 | return <input value={value} onChange={(e) => setValue(e.target.value)} />; |
| 9 | } |
| 10 |
|
| 11 | return ( |
| 12 | <div> |
| 13 | <Field /> |
| 14 | </div> |
| 15 | ); |
| 16 | } |
Explanation (EN)
Defining a component inside another component creates a new component type on each render. This can trigger remounting of the subtree, losing state and input focus.
Objašnjenje (HR)
Definiranje komponente unutar druge komponente stvara novu komponentnu 'vrstu' na svakom renderu. To moze uzrokovati remount podstabla, gubitak statea i focusa.
Good example
| 1 | import { useState } from "react"; |
| 2 |
|
| 3 | function Field({ value, onChange }: { value: string; onChange: (v: string) => void }) { |
| 4 | return <input value={value} onChange={(e) => onChange(e.target.value)} />; |
| 5 | } |
| 6 |
|
| 7 | export function Form() { |
| 8 | const [value, setValue] = useState(""); |
| 9 |
|
| 10 | return ( |
| 11 | <div> |
| 12 | <Field value={value} onChange={setValue} /> |
| 13 | </div> |
| 14 | ); |
| 15 | } |
Explanation (EN)
The child component is defined at module scope, so its identity is stable. The subtree doesn't remount on every parent render, preserving focus and state.
Objašnjenje (HR)
Dijete komponenta je definirana na razini modula, pa je identitet stabilan. Podstablo se ne remounta na svakom renderu parenta, pa se cuvaju focus i state.
Exceptions / Tradeoffs (EN)
Inline render helpers are fine if they are not React components (do not use hooks, do not hold state) and you accept they are not visible in DevTools as components.
Iznimke / Tradeoffi (HR)
Inline render helperi su ok ako nisu React komponente (ne koriste hookove, nemaju state) i prihvacas da se ne vide u DevTools kao komponente.