### Install and Run Development Server Source: https://github.com/alan2207/bulletproof-react/blob/master/AGENTS.md Navigate to the desired application directory, install dependencies, and start the development server. ```bash cd apps/react-vite # or apps/nextjs-app or apps/nextjs-pages yarn install yarn dev ``` -------------------------------- ### Start Mock Server Source: https://github.com/alan2207/bulletproof-react/blob/master/apps/nextjs-app/README.md Run this command to start the mock server. The mock server is accessible at http://localhost:8080/api. ```bash yarn run-mock-server ``` -------------------------------- ### Auth Configuration Example Source: https://github.com/alan2207/bulletproof-react/blob/master/docs/security.md Example of configuring authentication using react-query-auth. This setup handles user state management, including login, logout, and session persistence. ```typescript import { AuthProvider } from '@tanstack/react-query-auth'; import { authProvider } from '@/lib/auth'; export const Auth = ({ children, }: { children: React.ReactNode; }) => { return ; }; ``` -------------------------------- ### Clone and Install Next.js App Source: https://github.com/alan2207/bulletproof-react/blob/master/apps/nextjs-app/README.md Use these commands to clone the repository, navigate to the Next.js app directory, set up environment variables, and install dependencies. ```bash git clone https://github.com/alan2207/bulletproof-react.git cd bulletproof-react cd apps/nextjs-app cp .env.example .env yarn install ``` -------------------------------- ### Clone and Install React Vite App Source: https://github.com/alan2207/bulletproof-react/blob/master/apps/react-vite/README.md Use these commands to clone the repository, navigate to the app directory, set up environment variables, and install dependencies. ```bash git clone https://github.com/alan2207/bulletproof-react.git cd bulletproof-react cd apps/react-vite cp .env.example .env yarn install ``` -------------------------------- ### Clone and Install Next.js Pages App Source: https://github.com/alan2207/bulletproof-react/blob/master/apps/nextjs-pages/README.md Commands to clone the repository, navigate to the Next.js Pages application directory, copy environment variables, and install dependencies. ```bash git clone https://github.com/alan2207/bulletproof-react.git cd bulletproof-react cd apps/nextjs-pages cp .env.example .env yarn install ``` -------------------------------- ### Authorization Configuration Example (RBAC) Source: https://github.com/alan2207/bulletproof-react/blob/master/docs/security.md Configuration for Role-Based Access Control (RBAC) using a custom authorization provider. This example sets up roles and permissions for resource access. ```typescript import { createAuth } from '@api/auth'; import { authProvider } from './auth-provider'; export const { useAuth } = createAuth({ ...authProvider, roles: ['USER', 'ADMIN'], }); ``` -------------------------------- ### API Layer Fetcher and Hook Example Source: https://github.com/alan2207/bulletproof-react/blob/master/AGENTS.md Demonstrates the pattern for defining API fetcher functions and React Query hooks for data management. ```typescript // api/get-discussions.ts export const getDiscussions = (params: GetDiscussionsParams): Promise => { return api.get('/discussions', { params }); }; export const useDiscussions = (params: GetDiscussionsParams) => { return useQuery({ queryKey: ['discussions', params], queryFn: () => getDiscussions(params), }); }; ``` -------------------------------- ### Build React Vite App for Production Source: https://github.com/alan2207/bulletproof-react/blob/master/apps/react-vite/README.md Creates an optimized production build of the React Vite application in the `dist` folder. Refer to Vite's deployment guide for more information. ```bash yarn build ``` -------------------------------- ### Global State Management with Zustand Source: https://github.com/alan2207/bulletproof-react/blob/master/docs/state-management.md This example demonstrates a simple global state store using Zustand for managing notifications. It's suitable for application-wide state like modals or notifications. ```typescript import { create } from "zustand"; interface Notification { id: number; message: string; type: "success" | "error" | "info"; } interface NotificationState { notifications: Notification[]; addNotification: (message: string, type: "success" | "error" | "info") => void; removeNotification: (id: number) => void; } export const useNotificationStore = create((set) => ({ notifications: [], addNotification: (message, type) => set((state) => ({ notifications: [ ...state.notifications, { id: Date.now(), message, type }, ], })), removeNotification: (id) => set((state) => ({ notifications: state.notifications.filter((n) => n.id !== id), })), })); ``` -------------------------------- ### Configure and Reuse API Client Instance Source: https://github.com/alan2207/bulletproof-react/blob/master/docs/api-layer.md Instantiate and configure a single API client for consistent interaction with RESTful or GraphQL APIs throughout your application. This example uses the native fetch API. ```typescript import { type FetchResponse, type FetchRequest, } from "@/lib/fetcher"; export const apiClient = { get: (url: string) => fetcher(url), post: (url: string, body: Record) => fetcher(url, { method: "POST", body: JSON.stringify(body), }), put: (url: string, body: Record) => fetcher(url, { method: "PUT", body: JSON.stringify(body), }), delete: (url: string) => fetcher(url, { method: "DELETE", }), }; async function fetcher(request: FetchRequest): Promise> { const response = await fetch(request.url, { method: request.method, ...(request.body && { body: request.body, }), headers: { "Content-Type": "application/json", Accept: "application/json", }, }); if (!response.ok) { throw new Error(response.statusText); } const data = await response.json(); return { data, }; } // Define types for fetcher interface Fetcher { (request: FetchRequest): Promise>; } interface FetchResponse { data: T; } interface FetchRequest { url: string; method?: "GET" | "POST" | "PUT" | "DELETE"; body?: string; } ``` -------------------------------- ### Server Cache State with React Query Source: https://github.com/alan2207/bulletproof-react/blob/master/docs/state-management.md This example shows how to fetch and cache server state using React Query. It's designed for efficiently handling REST and GraphQL data. ```typescript import { useQuery } from "@tanstack/react-query"; interface Discussion { id: string; title: string; } async function fetchDiscussions(): Promise { const response = await fetch("/api/discussions"); if (!response.ok) { throw new Error("Network response was not ok"); } return response.json(); } export function useDiscussions() { return useQuery(["discussions"], fetchDiscussions); } ``` -------------------------------- ### HTML Sanitization Example Source: https://github.com/alan2207/bulletproof-react/blob/master/docs/security.md This snippet demonstrates how to sanitize HTML input to prevent Cross-Site Scripting (XSS) vulnerabilities. Ensure all user-generated content is sanitized before rendering. ```typescript import { DOMPurify } from 'dompurify'; export const sanitizeHtml = (unsafeHtml: string) => { return DOMPurify.sanitize(unsafeHtml); }; ``` -------------------------------- ### Unit Test Example for Confirmation Dialog Source: https://github.com/alan2207/bulletproof-react/blob/master/docs/testing.md This snippet demonstrates a unit test for a confirmation dialog component. It focuses on testing the component in isolation, ensuring its basic functionality works as expected. ```typescript import { render, screen, userEvent, } from "@testing-library/react"; import { ConfirmationDialog } from "./confirmation-dialog"; describe("ConfirmationDialog", () => { it("should render and confirm", async () => { const user = userEvent.setup(); const onConfirm = vi.fn(); const onCancel = vi.fn(); render( ); expect(screen.getByText("Test Title")).toBeInTheDocument(); expect(screen.getByText("Test Message")).toBeInTheDocument(); await user.click(screen.getByRole("button", { name: /confirm/i })); expect(onConfirm).toHaveBeenCalledTimes(1); await user.click(screen.getByRole("button", { name: /cancel/i })); expect(onCancel).toHaveBeenCalledTimes(1); }); it("should not call callbacks when dialog is closed", async () => { const onConfirm = vi.fn(); const onCancel = vi.fn(); render( ); expect(screen.queryByText("Test Title")).not.toBeInTheDocument(); expect(onConfirm).not.toHaveBeenCalled(); expect(onCancel).not.toHaveBeenCalled(); }); }); ``` -------------------------------- ### Define API Request Declarations - Query Source: https://github.com/alan2207/bulletproof-react/blob/master/docs/api-layer.md Define and export API request declarations separately for better code organization. This example shows a query declaration using react-query. ```typescript import { type UseQueryResult, useQuery, } from "@tanstack/react-query"; import { apiClient, type FetchResponse, } from "@/lib/api-client"; import { type Discussion, discussionSchema, } from "./discussion"; import { zodResolver, } from "@hookform/resolvers/zod"; import { z } from "zod"; const GET_DISCUSSIONS_QUERY_KEY = "discussions"; const discussionsSchema = z.array(discussionSchema); export const getDiscussions = { queryKey: [GET_DISCUSSIONS_QUERY_KEY], fetcher: () => apiClient.get>>("/discussions"), useQuery: (): UseQueryResult> => useQuery>({ queryKey: getDiscussions.queryKey, queryFn: getDiscussions.fetcher, }), schema: discussionsSchema, }; // Define types for Discussion export interface Discussion { id: number; title: string; body: string; created_at: string; updated_at: string; } // Define schema for Discussion const discussionSchema = z.object({ id: z.number(), title: z.string().min(1), body: z.string().min(1), created_at: z.string().datetime(), updated_at: z.string().datetime(), }); ``` -------------------------------- ### ESLint Rules for File and Folder Naming Conventions Source: https://github.com/alan2207/bulletproof-react/blob/master/docs/project-standards.md Enforce file and folder naming conventions using ESLint. This example enforces kebab-case for files and folders within the `src` directory, with an option to ignore middle extensions. ```javascript 'check-file/filename-naming-convention': [ 'error', { '**/*.{ts,tsx}': 'KEBAB_CASE', }, { // ignore the middle extensions of the filename to support filename like bable.config.js or smoke.spec.ts ignoreMiddleExtensions: true, }, ], 'check-file/folder-naming-convention': [ 'error', { // all folders within src (except __tests__)should be named in kebab-case 'src/**/!(__tests__)': 'KEBAB_CASE', }, ] ``` -------------------------------- ### Define API Request Declarations - Mutation Source: https://github.com/alan2207/bulletproof-react/blob/master/docs/api-layer.md Define and export API request declarations separately for better code organization. This example shows a mutation declaration using react-query. ```typescript import { type UseMutationResult, useMutation, } from "@tanstack/react-query"; import { apiClient, type FetchResponse, } from "@/lib/api-client"; import { type Discussion, discussionSchema, } from "./discussion"; import { zodResolver, } from "@hookform/resolvers/zod"; import { z } from "zod"; const CREATE_DISCUSSION_MUTATION_KEY = "createDiscussion"; const createDiscussionSchema = z.object({ title: z.string().min(1), body: z.string().min(1), }); export const createDiscussion = { mutationKey: [CREATE_DISCUSSION_MUTATION_KEY], fetcher: (discussion: z.infer) => apiClient.post>>( "/discussions", discussion ), useMutation: (): UseMutationResult< FetchResponse>, Error, z.infer > => useMutation({ mutationKey: createDiscussion.mutationKey, mutationFn: createDiscussion.fetcher, }), schema: createDiscussionSchema, }; // Define types for Discussion export interface Discussion { id: number; title: string; body: string; created_at: string; updated_at: string; } // Define schema for Discussion const discussionSchema = z.object({ id: z.number(), title: z.string().min(1), body: z.string().min(1), created_at: z.string().datetime(), updated_at: z.string().datetime(), }); ``` -------------------------------- ### Form Validation with Zod Source: https://github.com/alan2207/bulletproof-react/blob/master/docs/state-management.md Example of integrating Zod for client-side form input validation. This schema defines the expected structure and constraints for registration form fields. ```typescript import { z } from "zod"; export const registerSchema = z.object({ username: z.string().min(3, "Username must be at least 3 characters long"), email: z.string().email("Invalid email address"), password: z.string().min(6, "Password must be at least 6 characters long"), }); export type RegisterSchema = z.infer; ``` -------------------------------- ### Data Models Example for Mock Database Source: https://github.com/alan2207/bulletproof-react/blob/master/docs/testing.md This code defines data models for a mock database using MSW. It sets up the structure for entities like users, posts, and comments, enabling the creation of realistic mock data for testing purposes. ```typescript import { factory, primaryKey } from "@mswjs/data"; export const db = factory({ user: { id: primaryKey(1), email: String, name: String, createdAt: () => new Date(), }, post: { id: primaryKey(1), title: String, content: String, authorId: Number, createdAt: () => new Date(), }, comment: { id: primaryKey(1), text: String, postId: Number, authorId: Number, createdAt: () => new Date(), }, }); ``` -------------------------------- ### Feature Module Structure Source: https://github.com/alan2207/bulletproof-react/blob/master/docs/project-structure.md An example of the internal structure for a specific feature module within the 'src/features' directory. This structure helps in organizing code related to a particular feature, including its API, assets, components, hooks, stores, types, and utilities. ```sh src/features/awesome-feature | +-- api # exported API request declarations and api hooks related to a specific feature | +-- assets # assets folder can contain all the static files for a specific feature | +-- components # components scoped to a specific feature | +-- hooks # hooks scoped to a specific feature | +-- stores # state stores for a specific feature | +-- types # typescript types used within the feature | +-- utils # utility functions for a specific feature ``` -------------------------------- ### Integration Test Example for Discussions Route Source: https://github.com/alan2207/bulletproof-react/blob/master/docs/testing.md This integration test verifies the functionality of the discussions route within the application. It checks if discussions are fetched and displayed correctly, ensuring components interact as expected. ```typescript import { render, screen, waitFor, } from "@testing-library/react"; import { Discussions } from "./discussion"; import { server } from "../../../../mocks/server"; import { discussionsHandler, discussionDetailsHandler, } from "../../../../mocks/handlers/discussion"; import { BrowserRouter as Router, Route, Routes } from "react-router-dom"; describe("Discussions", () => { beforeAll(() => { server.listen(); }); afterEach(() => { server.resetHandlers(); }); afterAll(() => { server.close(); }); it("should render discussions and allow navigation to details", async () => { server.use(discussionsHandler()); server.use(discussionDetailsHandler()); render( } /> Discussion Details} /> ); // Wait for the discussions to be loaded and displayed await waitFor(() => { expect(screen.getByText("Discussion 1")).toBeInTheDocument(); expect(screen.getByText("Discussion 2")).toBeInTheDocument(); }); // Simulate clicking on a discussion to navigate to details // await userEvent.click(screen.getByText("Discussion 1")); // Wait for the discussion details to be loaded // await waitFor(() => { // expect(screen.getByText("Discussion Details")).toBeInTheDocument(); // }); }); }); ``` -------------------------------- ### E2E Smoke Test Example Source: https://github.com/alan2207/bulletproof-react/blob/master/docs/testing.md This E2E test performs a smoke test on the application, verifying critical paths and basic functionality. It simulates user interactions to ensure the application is stable and usable from end-to-end. ```typescript import { test, expect } from "@playwright/test"; test.describe("Smoke Test", () => { test("should navigate to the home page and verify content", async ({ page }) => { await page.goto("/"); await expect(page).toHaveTitle(/React App/); await expect(page.locator("h1")).toContainText("Welcome"); }); test("should navigate to login page and verify form elements", async ({ page }) => { await page.goto("/login"); await expect(page.locator("input[name='email']")).toBeVisible(); await expect(page.locator("input[name='password']")).toBeVisible(); await expect(page.locator("button[type='submit']")).toBeVisible(); }); }); ``` -------------------------------- ### API Handlers Example for Authentication Source: https://github.com/alan2207/bulletproof-react/blob/master/docs/testing.md This snippet defines API handlers for authentication using MSW (Mock Service Worker). It intercepts specific API requests and returns predefined responses, useful for frontend development and testing without a live backend. ```typescript import { rest } from "msw"; import { User } from "../models/user"; const authHandlers = [ rest.post("/api/login", (req, res, ctx) => { const { email, password } = req.body; if (email === "test@example.com" && password === "password123") { return res( ctx.status(200), ctx.json({ id: "1", email, name: "Test User", }) ); } return res( ctx.status(401), ctx.json({ message: "Invalid credentials", }) ); }), rest.post("/api/logout", (req, res, ctx) => { return res( ctx.status(200), ctx.json({ message: "Successfully logged out", }) ); }), ]; export default authHandlers; ``` -------------------------------- ### PBAC Example: Comments List Source: https://github.com/alan2207/bulletproof-react/blob/master/docs/security.md This component demonstrates Permission-Based Access Control (PBAC) by allowing only the owner of a comment to delete it. It checks if the current user is the author before rendering the delete option. ```typescript import { useAuth } from '@/lib/auth'; import { Button } from '@/components/ui/button'; interface CommentProps { comment: { id: string; text: string; authorId: string; }; } export const Comment = ({ comment, }: CommentProps) => { const { data: user } = useAuth(); const isOwner = user?.id === comment.authorId; return (

{comment.text}

{isOwner && ( )}
); }; ``` -------------------------------- ### RBAC Example: Delete Discussion Button Source: https://github.com/alan2207/bulletproof-react/blob/master/docs/security.md This component conditionally renders a delete button based on user roles, demonstrating Role-Based Access Control (RBAC). Only users with the 'ADMIN' role can see and use this button. ```typescript import { useAuth } from '@/lib/auth'; import { Button } from '@/components/ui/button'; interface DeleteDiscussionProps { discussionId: string; } export const DeleteDiscussion = ({ discussionId, }: DeleteDiscussionProps) => { const { data: user } = useAuth(); if (user?.role !== 'ADMIN') return null; return ( ); }; ``` -------------------------------- ### Run Next.js App in Development Source: https://github.com/alan2207/bulletproof-react/blob/master/apps/nextjs-app/README.md Execute this command to run the Next.js application in development mode. Access the app at http://localhost:3000 in your browser. ```bash yarn dev ``` -------------------------------- ### Run Tests and Lint Code Source: https://github.com/alan2207/bulletproof-react/blob/master/AGENTS.md Commands to execute tests, end-to-end tests, and lint the codebase. ```bash yarn test yarn test:e2e yarn lint ``` -------------------------------- ### Project Directory Structure Source: https://github.com/alan2207/bulletproof-react/blob/master/AGENTS.md Overview of the main directories within the React application's source code. ```plaintext src/ ├── app/ # Application layer (routes, providers, router) ├── components/ # Shared UI components ├── config/ # Global configurations and env variables ├── features/ # Feature-based modules (auth, discussions, comments, etc.) ├── hooks/ # Shared React hooks ├── lib/ # Preconfigured libraries (react-query, auth, etc.) ├── testing/ # Test utilities and mocks ├── types/ # Shared TypeScript types └── utils/ # Shared utility functions ``` -------------------------------- ### Configure Absolute Imports for JavaScript Projects Source: https://github.com/alan2207/bulletproof-react/blob/master/docs/project-standards.md Set up absolute imports in `jsconfig.json` for JavaScript projects. This simplifies import paths by allowing imports relative to the project root, aliased as '@/*'. ```json { "compilerOptions": { "baseUrl": ".", "paths": { "@/*": ["./src/*"] } } } ``` -------------------------------- ### Main Application Structure Source: https://github.com/alan2207/bulletproof-react/blob/master/docs/project-structure.md This is the top-level structure for the 'src' directory in a React application. It includes folders for application logic, assets, shared components, configuration, features, hooks, libraries, stores, testing utilities, types, and general utility functions. ```sh src | +-- app # application layer containing: | | # this folder might differ based on the meta framework used | +-- routes # application routes / can also be pages | +-- app.tsx # main application component | +-- provider.tsx # application provider that wraps the entire application with different global providers - this might also differ based on meta framework used | +-- router.tsx # application router configuration +-- assets # assets folder can contain all the static files such as images, fonts, etc. | +-- components # shared components used across the entire application | +-- config # global configurations, exported env variables etc. | +-- features # feature based modules | +-- hooks # shared hooks used across the entire application | +-- lib # reusable libraries preconfigured for the application | +-- stores # global state stores | +-- testing # test utilities and mocks | +-- types # shared types used across the application | +-- utils # shared utility functions ``` -------------------------------- ### Prettier Configuration File Source: https://github.com/alan2207/bulletproof-react/blob/master/docs/project-standards.md Define code formatting rules in `.prettierrc` to ensure consistent code style across the project. This file is used by Prettier to automatically format code. ```json { "semi": true, "trailingComma": "all", "singleQuote": true, "printWidth": 100, "tabWidth": 2, "endOfLine": "lf" } ``` -------------------------------- ### Enforce Unidirectional Codebase: App to Features Source: https://github.com/alan2207/bulletproof-react/blob/master/docs/project-structure.md Configure import rules to ensure that the 'src/app' directory can import from 'src/features', but not vice versa. This enforces a clear dependency direction. ```javascript { target: './src/features', from: './src/app', } ``` -------------------------------- ### ESLint Configuration for React Vite Project Source: https://github.com/alan2207/bulletproof-react/blob/master/docs/project-standards.md Configure ESLint rules in `.eslintrc.js` to maintain code quality and consistency in a React Vite project. This helps identify and prevent common errors. ```javascript { "extends": [ "eslint:recommended", "plugin:@typescript-eslint/recommended", "plugin:react/recommended", "plugin:react-hooks/recommended", "plugin:jsx-a11y/recommended", "plugin:prettier/recommended" ], "parserOptions": { "ecmaVersion": "latest", "sourceType": "module" }, "plugins": [ "@typescript-eslint", "react", "react-hooks", "jsx-a11y" ], "rules": { "react/react-in-jsx-scope": "off", "react/prop-types": "off", "@typescript-eslint/explicit-function-return-type": "warn", "@typescript-eslint/no-explicit-any": "warn", "no-unused-vars": "warn", "react-hooks/exhaustive-deps": "warn", "jsx-a11y/anchor-is-valid": [ "warn", { "components": ["Link"], "specialLink": ["hrefLeft", "hrefRight"], "aspects": ["invalidHref", "missingHref", "disable"] } ] }, "settings": { "react": { "version": "detect" } } } ``` -------------------------------- ### React State Initializer Function Source: https://github.com/alan2207/bulletproof-react/blob/master/docs/performance.md Use a state initializer function with `useState` to ensure expensive computations are only run once during the initial render, preventing re-renders. ```javascript const [state, setState] = React.useState(() => myExpensiveFn()); ``` -------------------------------- ### Optimizing Components with Children Prop Source: https://github.com/alan2207/bulletproof-react/blob/master/docs/performance.md Pass JSX as the `children` prop to prevent parent components from causing unnecessary re-renders of child components. The `children` prop represents an isolated VDOM structure. ```javascript // Not optimized example const App = () => ; const Counter = () => { const [count, setCount] = useState(0); return (
// will rerender whenever "count" updates
); }; const PureComponent = () =>

Pure Component

; ``` ```javascript // Optimized example const App = () => ( ); const Counter = ({ children }) => { const [count, setCount] = useState(0); return (
{children} // won't rerender whenever "count" updates
); }; const PureComponent = () =>

Pure Component

; ``` -------------------------------- ### Extracting UI into Separate Components Source: https://github.com/alan2207/bulletproof-react/blob/master/docs/components-and-styling.md Avoid large components with nested rendering functions by extracting reusable UI pieces into separate components. This improves maintainability and readability. ```javascript function Component() { function renderItems() { return
    ...
; } return
{renderItems()}
; } function Items() { return
    ...
; } function Component() { return (
); } ``` -------------------------------- ### Shared Modules Import Rules in React Source: https://github.com/alan2207/bulletproof-react/blob/master/docs/project-structure.md Define rules for shared modules like components, hooks, and utilities. 'src/app' and 'src/features' can import from these shared directories, but the shared directories cannot import from 'src/app' or 'src/features'. This prevents circular dependencies and maintains modularity. ```javascript { target: [ './src/components', './src/hooks', './src/lib', './src/types', './src/utils', ], from: ['./src/features', './src/app'], } ``` -------------------------------- ### Feature Module Structure Source: https://github.com/alan2207/bulletproof-react/blob/master/AGENTS.md Defines the self-contained structure for each feature module within the application. ```plaintext src/features/awesome-feature/ ├── api/ # API calls and hooks for this feature ├── components/ # Feature-specific components ├── hooks/ # Feature-specific hooks ├── stores/ # Feature-specific state ├── types/ # Feature-specific types └── utils/ # Feature-specific utilities ``` -------------------------------- ### Component State with useState and useReducer Source: https://github.com/alan2207/bulletproof-react/blob/master/docs/state-management.md Use useState for simple, independent states and useReducer for complex states where a single action updates multiple pieces of state. These are typically defined within the component itself. ```typescript import { useState, useReducer, type Dispatch, type SetStateAction, } from "react"; interface State { count: number; step: number; } interface Action { type: "INCREMENT" | "DECREMENT" | "SET_STEP"; payload?: number; } const initialState: State = { count: 0, step: 1, }; function reducer(state: State, action: Action): State { switch (action.type) { case "INCREMENT": return { ...state, count: state.count + state.step }; case "DECREMENT": return { ...state, count: state.count - state.step }; case "SET_STEP": return { ...state, step: action.payload ?? 1 }; default: return state; } } export function DashboardLayout() { const [count, setCount] = useState(0); const [state, dispatch] = useReducer(reducer, initialState); return (

Component State Example

Simple State (useState): {count}

Complex State (useReducer): Count = {state.count}, Step = {state.step}

dispatch({ type: "SET_STEP", payload: parseInt(e.target.value, 10) }) } className="p-2 border border-gray-300 rounded-md" placeholder="Set Step" />
); } ``` -------------------------------- ### ESLint Rule: Disallow Restricted Paths Source: https://github.com/alan2207/bulletproof-react/blob/master/docs/project-structure.md This ESLint configuration restricts cross-feature imports within the 'src/features' directory. It's used to enforce a modular architecture by preventing direct imports between different feature modules, promoting independence and maintainability. ```js 'import/no-restricted-paths': [ 'error', { zones: [ // disables cross-feature imports: // eg. src/features/discussions should not import from src/features/comments, etc. { target: './src/features/auth', from: './src/features', except: ['./auth'], }, { target: './src/features/comments', from: './src/features', except: ['./comments'], }, { target: './src/features/discussions', from: './src/features', except: ['./discussions'], }, { target: './src/features/teams', from: './src/features', except: ['./teams'], }, { target: './src/features/users', from: './src/features', except: ['./users'], }, // More restrictions... ], }, ], ``` -------------------------------- ### Input Field Component Source: https://github.com/alan2207/bulletproof-react/blob/master/docs/state-management.md A reusable input field component designed to work with form management libraries. It includes label, input element, and error message display. ```typescript import React from "react"; import { useFormContext, type UseFormReturn, type FieldValues, type Path, } from "react-hook-form"; interface InputProps { name: Path; label: string; type?: string; placeholder?: string; } export function Input( { name, label, type = "text", placeholder, }: InputProps, ): React.ReactElement { const { register, formState: { errors } } = useFormContext(); const error = errors[name] as unknown as { message?: string; }; return (
{error?.message && (

{error.message}

)}
); } ``` -------------------------------- ### ESLint Rule: Enforce Unidirectional Architecture Source: https://github.com/alan2207/bulletproof-react/blob/master/docs/project-structure.md This ESLint configuration helps enforce a unidirectional data flow architecture. It restricts imports to ensure that code flows predictably from shared parts to features, and from features to the application layer, enhancing predictability and understandability. ```js 'import/no-restricted-paths': [ 'error', { zones: [ // Previous restrictions... ``` -------------------------------- ### Form Component with React Hook Form Source: https://github.com/alan2207/bulletproof-react/blob/master/docs/state-management.md Abstracted Form component using React Hook Form for streamlined form management, including validation and submission. This component wraps library functionality for application-specific needs. ```typescript import React from "react"; import { useFormContext, type UseFormReturn, type FieldValues, type Path, } from "react-hook-form"; interface FormProps { children: React.ReactNode; methods: UseFormReturn; onSubmit: (data: TFieldValues) => void; } export function Form( { children, methods, onSubmit, }: FormProps, ): React.ReactElement { return (
{children}
); } interface InputProps { name: Path; label: string; type?: string; placeholder?: string; } export function Input( { name, label, type = "text", placeholder, }: InputProps, ): React.ReactElement { const { register, formState: { errors } } = useFormContext(); const error = errors[name] as unknown as { message?: string; }; return (
{error?.message && (

{error.message}

)}
); } ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.