react Rules

10 rules found for react

Enforce component design system in React

All design system components must use forwardRef pattern, CVA for variants, and follow the established component structure. Bad: `typescript interface ButtonProps { className?: string variant?: string size?: string children: React.ReactNode } const Button = ({ className, variant, size, children, ...props }: ButtonProps) => { let baseClasses = "inline-flex items-center justify-center rounded-md text-sm font-medium" if (variant === "destructive") { baseClasses += " bg-red-500 text-white" } else { baseClasses += " bg-blue-500 text-white" } if (size === "sm") { baseClasses += " h-9 px-3" } else { baseClasses += " h-10 px-4 py-2" } return ( <button className={${baseClasses} ${className}} {...props}> {children} </button> ) } ` Good: `typescript import { cva, type VariantProps } from "class-variance-authority" import { clx } from "../utils" const buttonVariants = cva( "inline-flex items-center justify-center rounded-md text-sm font-medium", { variants: { variant: { default: "bg-primary text-primary-foreground hover:bg-primary/90", destructive: "bg-destructive text-destructive-foreground hover:bg-destructive/90", }, size: { default: "h-10 px-4 py-2", sm: "h-9 rounded-md px-3", }, }, defaultVariants: { variant: "default", size: "default", }, } ) export interface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement>, VariantProps<typeof buttonVariants> {} const Button = React.forwardRef<HTMLButtonElement, ButtonProps>( ({ className, variant, size, ...props }, ref) => { return ( <button className={clx(buttonVariants({ variant, size }), className)} ref={ref} {...props} /> ) } ) Button.displayName = "Button" export { Button, buttonVariants } `

nextjs

react

typescript

Check for duplicate components

Favor existing components over creating new ones. Before creating a new component, check if an existing component can satisfy the requirements through its props and parameters. Bad: `tsx // Creating a new component that duplicates functionality export function FormattedDate({ date, variant }) { // Implementation that duplicates existing functionality return <span>{/ formatted date /}</span> } ` Good: `tsx // Using an existing component with appropriate parameters import { DateTime } from "./DateTime" function Page() { return <DateTime date={date} variant={variant} noTrigger={true} /> } `

nextjs

react

typescript

Internal links in React

When linking between internal sites, use rel="noopener" instead of rel="noopener noreferrer". Bad: `jsx // For internal links, don't use noreferrer <Link to="/dashboard" rel="noopener noreferrer">Dashboard</Link> // Or with anchor tags <a href="/about" rel="noopener noreferrer">About Us</a> ` Good: `jsx // For internal links, only use noopener <Link to="/dashboard" rel="noopener">Dashboard</Link> // Or with anchor tags <a href="/about" rel="noopener">About Us</a> // For external links, noreferrer can be appropriate <a href="https://external-site.com" rel="noopener noreferrer" target="_blank">External Site</a> `

react

typescript

No random numbers in React

Do not generate non-deterministic values like random IDs during render in React components. This causes hydration errors because the server-rendered HTML will not match what the client generates. Avoid using functions like Math.random(), Date.now(), uuid(), or any other source of randomness directly in your render function or JSX. Instead: - Generate IDs in useEffect hooks - Use stable IDs based on props or state - Use refs to store generated values - Use libraries that support SSR (like uuid with specific configuration) Bad: `tsx function UserCard() { // This will generate different values on server and client const id = user-${Math.random()} return ( <div id={id}> <input aria-labelledby={label-${Math.floor(Math.random() * 1000)}} /> </div> ) } ` Good: `tsx function UserCard({ userId }) { // Using stable props for IDs const id = user-${userId} // For dynamic IDs, use useEffect and useState const [randomId, setRandomId] = useState(null) useEffect(() => { // Generate random values after mounting setRandomId(label-${Math.floor(Math.random() * 1000)}) }, []) return <div id={id}>{randomId && <input aria-labelledby={randomId} />}</div> } `

nextjs

react

typescript

No unused components

Do not leave commented-out components. Either remove unused components entirely or implement them properly. Bad: `tsx function MyComponent() { return ( <div> <Header /> {/* <Sidebar> <Navigation /> </Sidebar> */} <MainContent /> </div> ) } ` Good: `tsx function MyComponent() { return ( <div> <Header /> <MainContent /> </div> ) } `

nextjs

react

typescript

Always return empty arrays in Typescript

When defining methods that return collections like arrays, always return an empty array instead of undefined when no items exist. Bad: `typescript function getUserNames(): string[] | undefined { if (users.length === 0) { return undefined } return users.map((user) => user.name) } ` Good: `typescript function getUserNames(): string[] { if (users.length === 0) { return [] } return users.map((user) => user.name) } `

typescript

react

Avoid duplicate words in Typescript

Check all text elements (comments, docstrings, and string literals) for duplicate adjacent words for typos or duplicates. Bad: `typescript // This function validates the the input parameters function validateInput() { ... } ` Good: `typescript // This function validates the input parameters function validateInput() { ... } `

typescript

react

Dev dependencies in typescript

Place CLI tool dependencies in the devDependencies section of package.json instead of dependencies when they are only used for local development, scripts, or tooling. Bad: `json { "dependencies": { "@eslint/eslintrc": "^3", "@tailwindcss/postcss": "^4.1.6", "@types/node": "^20" } } ` Good: `json { "devDependencies": { "@eslint/eslintrc": "^3", "@tailwindcss/postcss": "^4.1.6", "@types/node": "^20" } } `

typescript

react

nextjs

Typescript DRY

Avoid duplicating code in TypeScript. Extract repeated logic into reusable functions, types, or constants. You may have to search the codebase to see if the method or type is already defined. Bad: `typescript // Duplicated type definitions interface User { id: string name: string } interface UserProfile { id: string name: string } // Magic numbers repeated const pageSize = 10 const itemsPerPage = 10 ` Good: `typescript // Reusable type and constant type User = { id: string name: string } const PAGE_SIZE = 10 `

typescript

nextjs

react

Query standards for Tanstack Query

When using TanStack Query (React Query), always configure cache and refetching behavior explicitly: 1. Set appropriate staleTime based on how frequently the data changes 2. Configure all refetching flags explicitly to prevent unnecessary network requests Bad: `tsx const { data } = useQuery({ queryKey: ["resource", id], queryFn: () => fetchResource(id), refetchOnMount: false, // Missing staleTime and other refetching settings }) ` Good: `tsx const { data } = useQuery({ queryKey: ["resource", id], queryFn: () => fetchResource(id), refetchOnMount: false, refetchOnWindowFocus: false, refetchOnReconnect: false, staleTime: 5 60 1000, // 5 minutes }) `

typescript

react

nextjs