Skip to content

feat: centralize state management with React Context#3

Open
shivv23 wants to merge 9 commits into
IPFS-Meshkit:mainfrom
shivv23:feat/react-context-state-management
Open

feat: centralize state management with React Context#3
shivv23 wants to merge 9 commits into
IPFS-Meshkit:mainfrom
shivv23:feat/react-context-state-management

Conversation

@shivv23

@shivv23 shivv23 commented Jul 21, 2026

Copy link
Copy Markdown

Introduces React Context to centralize shared state management, eliminating prop drilling across the Home route component tree.

Motivation

All shared state (selectedFile, billType, showMenu) was owned by Home.tsx and passed as props to Dashboard, NewFile, and Menu. Additionally, a Local store instance was created inside the component body on every render — a performance anti-pattern that allocates a new object each cycle.

Changes

New context providers (src/contexts/):

  • StoreContext.tsx — provides a singleton Local instance via useMemo, wrapped in a useStore() hook. Mounted at the App level so both Home and MeshKitPage share the same instance.
  • InvoiceContext.tsx — provides selectedFile, billType, showMenu and their setters via a useInvoice() hook. Mounted at the Home level where the state is owned.

Refactored components:

Component Before After
Home.tsx Owned state, passed 4-6 props to each child Provides InvoiceContext, renders children with zero props
Dashboard.tsx Received store, currentBillType, onOpenFile as props Consumes useStore() and useInvoice(), receives only onOpenFile
NewFile.tsx Received file, store, billType, updateSelectedFile as props Consumes useStore() and useInvoice(), zero props
Menu.tsx Received showM, setM, file, updateSelectedFile, store, bT as props Consumes useStore() and useInvoice(), zero props
MeshKitPage.tsx Created new Local() on every render Consumes useStore() for singleton instance

App.tsx — wraps the router in <StoreProvider> to make the singleton store available app-wide.

Dead code removal:

  • Deleted src/components/Files/ (346 lines) — never imported by any component, legacy artifact superseded by Dashboard.

Type infrastructure:

  • Added src/types/meshkit-ionic.d.ts type declaration stub for @meshkit/ionic (local file dependency without published types).

Architecture

<App>
  <StoreProvider>              // singleton Local instance
    <Home>
      <InvoiceContext.Provider>  // selectedFile, billType, showMenu
        <Dashboard />           // useStore() + useInvoice()
        <NewFile />             // useStore() + useInvoice()
        <Menu />                // useStore() + useInvoice()
      </InvoiceContext.Provider>
    </Home>
    <MeshKitPage />             // useStore() only
  </StoreProvider>
</App>

Benefits

  • No more prop drilling — consumers access shared state directly via hooks
  • Consistent namingselectedFile and billType everywhere (no more file/bT/currentBillType variants)
  • Singleton storeuseMemo ensures one Local instance across all renders
  • Type-safe context — custom hooks throw if used outside their provider, catching misconfiguration at runtime
  • ~376 lines of dead code removed (Files component)

Verification

npx tsc --noEmit passes with zero errors (excluding the pre-existing @meshkit/ionic module resolution addressed by PR #1).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant