logo
  • Guide
  • API
  • Blog
  • English
    • 简体中文
    • English
    • @esmx/core
      Esmx
      App
      RenderContext
      ModuleConfig
      PackConfig
      ManifestJson
      @esmx/router
      Router
      Route
      Route Configuration
      RouterLink
      Navigation Guards
      Dynamic Route Matching
      Nested Routes
      Programmatic Navigation
      Scroll Behavior
      Layer Routing
      MicroApp
      Error Types
      Types Reference
      @esmx/router-vue
      RouterPlugin
      Composables
      Components
      Type Augmentation
      @esmx/router-react
      Micro-App Integration
      Hooks & Context
      Components
      SSR
      App
      @esmx/rspack
      @esmx/rspack-vue
      @esmx/rspack-react

      Last Updated: 4/7/2026, 2:16:07 AM

      Previous pageMicro-App IntegrationNext pageComponents

      #Hooks & Context

      #Introduction

      Since React does not have a dedicated @esmx/router integration package, you implement your own hooks and context providers using standard React patterns. This page documents the recommended implementation for useRouter(), useRoute(), and RouterProvider.

      #RouterProvider

      • Props:
        • router: Router — Router instance to provide
        • children: React.ReactNode — Child components
      • Returns: JSX.Element

      Context provider component that makes the router instance available to all descendant components via useRouter() and useRoute().

      import { createContext } from 'react';
      import type { Router } from '@esmx/router';
      
      const RouterContext = createContext<Router | null>(null);
      
      export function RouterProvider({
          router,
          children
      }: {
          router: Router;
          children: React.ReactNode;
      }) {
          return (
              <RouterContext.Provider value={router}>
                  {children}
              </RouterContext.Provider>
          );
      }

      #useRouter()

      • Returns: Router
      • Throws: Error — If called outside a RouterProvider

      Gets the router instance via React context. Equivalent to useRouter() in @esmx/router-vue.

      import { useContext } from 'react';
      import type { Router } from '@esmx/router';
      
      export function useRouter(): Router {
          const router = useContext(RouterContext);
          if (!router) {
              throw new Error('useRouter must be used within a RouterProvider');
          }
          return router;
      }

      #Usage

      function NavigationButtons() {
          const router = useRouter();
      
          return (
              <div>
                  <button onClick={() => router.push('/home')}>Home</button>
                  <button onClick={() => router.back()}>Back</button>
              </div>
          );
      }

      #useRoute()

      • Returns: Route
      • Throws: Error — If called outside a RouterProvider

      Gets the current reactive route object. Uses useSyncExternalStore for optimal React integration — the component re-renders automatically when the route changes. Equivalent to useRoute() in @esmx/router-vue.

      import { useSyncExternalStore } from 'react';
      import type { Route } from '@esmx/router';
      
      export function useRoute(): Route {
          const router = useRouter();
      
          return useSyncExternalStore(
              (callback) => router.afterEach(callback),
              () => router.route,
              () => router.route
          );
      }

      #Usage

      function CurrentPath() {
          const route = useRoute();
      
          return (
              <div>
                  <p>Path: {route.path}</p>
                  <p>Params: {JSON.stringify(route.params)}</p>
                  <p>Query: {JSON.stringify(route.query)}</p>
              </div>
          );
      }

      #Full Implementation

      Complete reference implementation combining all hooks and the provider:

      import { createContext, useContext, useSyncExternalStore } from 'react';
      import type { Router, Route } from '@esmx/router';
      
      // Context
      const RouterContext = createContext<Router | null>(null);
      
      // Provider
      export function RouterProvider({
          router,
          children
      }: {
          router: Router;
          children: React.ReactNode;
      }) {
          return (
              <RouterContext.Provider value={router}>
                  {children}
              </RouterContext.Provider>
          );
      }
      
      // Hooks
      export function useRouter(): Router {
          const router = useContext(RouterContext);
          if (!router) {
              throw new Error('useRouter must be used within a RouterProvider');
          }
          return router;
      }
      
      export function useRoute(): Route {
          const router = useRouter();
      
          return useSyncExternalStore(
              (callback) => router.afterEach(callback),
              () => router.route,
              () => router.route
          );
      }