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