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).
Decouple presentational components from domain entities
Avoid passing raw API objects to UI components; pass explicit, pre-formatted props to improve reusability and separation of concerns.
Bad example
| 1 | type ArticleCardProps = { |
| 2 | article: ApiArticle; // Coupled to backend shape |
| 3 | }; |
| 4 |
|
| 5 | export const ArticleCard = ({ article }: ArticleCardProps) => { |
| 6 | // Transformation/Formatting logic inside the UI component |
| 7 | const authorName = `${article.author.firstName} ${article.author.lastName}`; |
| 8 | const publishedDate = new Date(article.publishedAt).toLocaleDateString(); |
| 9 | const imageUrl = article.media?.url || '/placeholder.png'; |
| 10 |
|
| 11 | return ( |
| 12 | <div className="card"> |
| 13 | <img src={imageUrl} alt={article.title} /> |
| 14 | <h3>{article.title}</h3> |
| 15 | <span>{authorName} - {publishedDate}</span> |
| 16 | </div> |
| 17 | ); |
| 18 | }; |
Explanation (EN)
The component takes a raw API object (`article`) and performs data transformation (formatting names, dates, fallbacks) internally. This couples the UI to the backend schema, making the component hard to reuse with different data sources and harder to test.
Objašnjenje (HR)
Komponenta prima sirovi API objekt (`article`) i interno izvodi transformaciju podataka (formatiranje imena, datuma, zamjenske vrijednosti). To veže UI za backend shemu, otežavajući ponovnu upotrebu komponente s drugim izvorima podataka i njezino testiranje.
Good example
| 1 | type ArticleCardProps = { |
| 2 | title: string; |
| 3 | authorName: string; |
| 4 | publishedDate: string; |
| 5 | imageUrl: string; |
| 6 | }; |
| 7 |
|
| 8 | // Pure presentational component receiving flattened, ready-to-use props |
| 9 | export const ArticleCard = ({ |
| 10 | title, |
| 11 | authorName, |
| 12 | publishedDate, |
| 13 | imageUrl |
| 14 | }: ArticleCardProps) => { |
| 15 | return ( |
| 16 | <div className="card"> |
| 17 | <img src={imageUrl} alt={title} /> |
| 18 | <h3>{title}</h3> |
| 19 | <span>{authorName} - {publishedDate}</span> |
| 20 | </div> |
| 21 | ); |
| 22 | }; |
Explanation (EN)
The component receives explicit primitives (`title`, `authorName`) as props. The transformation logic is moved to the parent component or a mapper function. The component is now 'dumb', reusable, and strictly focused on rendering.
Objašnjenje (HR)
Komponenta prima eksplicitne primitive (`title`, `authorName`) kao props-e. Logika transformacije premještena je u roditeljsku komponentu ili funkciju za mapiranje. Komponenta je sada 'glupa', ponovno iskoristiva i strogo fokusirana na prikaz.
Notes (EN)
If passing many props becomes cumbersome, define a specific UI interface (e.g., `ArticleUiModel`) that is distinct from the API entity.
Bilješke (HR)
Ako slanje puno props-a postane nepraktično, definirajte specifično UI sučelje (npr. `ArticleUiModel`) koje je odvojeno od API entiteta.