Skip to content

useRouter ​

Hook to access the router instance from RouterProvider context. Returns the router with all stores bound to their current values using useUnit.

Import ​

ts
import { useRouter } from '@effector/router-react';

Usage ​

tsx
import { useRouter } from '@effector/router-react';

function Navigation() {
  const router = useRouter();

  return <button onClick={() => router.back()}>Go Back</button>;
}

Return Value ​

Returns the router instance with all store values automatically bound (not stores themselves):

tsx
function Component() {
  const router = useRouter();

  // Access current values (NOT stores)
  router.$path; // string (current path value)
  router.$query; // Query (current query value)
  router.$activeRoutes; // Route<any>[] (current active routes)

  // Navigation methods
  router.back(); // Go back
  router.forward(); // Go forward
  router.navigate({ path: '/home' });

  // ...other router properties
}

INFO

useRouter() uses useUnit internally to bind all stores to their values. The component will automatically re-render when any store value changes.

Examples ​

tsx
import { useRouter } from '@effector/router-react';

function HistoryControls() {
  const router = useRouter();

  return (
    <div>
      <button onClick={() => router.back()}>← Back</button>
      <button onClick={() => router.forward()}>Forward →</button>
    </div>
  );
}

Custom Navigation ​

tsx
import { useRouter } from '@effector/router-react';

function SearchForm() {
  const router = useRouter();
  const [query, setQuery] = useState('');

  const handleSubmit = () => {
    router.navigate({
      path: '/search',
      query: { q: query },
    });
  };

  return (
    <form onSubmit={handleSubmit}>
      <input value={query} onChange={(e) => setQuery(e.target.value)} />
      <button>Search</button>
    </form>
  );
}

Track Active Routes ​

tsx
import { useRouter } from '@effector/router-react';

function Breadcrumbs() {
  const router = useRouter();
  // router.$activeRoutes is already the value, not a store
  const activeRoutes = router.$activeRoutes;

  return (
    <nav>
      {activeRoutes.map((route, index) => (
        <span key={index}> / {route.path}</span>
      ))}
    </nav>
  );
}

Read Current Path ​

tsx
import { useRouter } from '@effector/router-react';

function CurrentPath() {
  const router = useRouter();
  // router.$path is already the value, not a store
  const path = router.$path;

  return <div>Current path: {path}</div>;
}

Error Handling ​

The hook throws an error if used outside of RouterProvider:

tsx
function Component() {
  // ❌ Error: Router not found. Add RouterProvider in app root
  const router = useRouter();
}

Always wrap your app with RouterProvider:

tsx
import { RouterProvider } from '@effector/router-react';

function App() {
  return (
    <RouterProvider router={router}>
      <YourApp />
    </RouterProvider>
  );
}

See Also ​

useRouterContext ​

useRouterContext is a public hook that returns the raw router from RouterProvider. Unlike useRouter, it leaves router stores unbound so you can select and bind them with useUnit.

Alternative hook that returns the raw router with stores (not values):

ts
import { useRouterContext } from '@effector/router-react';
tsx
import { useRouterContext } from '@effector/router-react';
import { useUnit } from 'effector-react';

function Component() {
  const router = useRouterContext();

  // router.$path is a Store<string>, must bind with useUnit
  const path = useUnit(router.$path);

  // Or bind multiple stores at once
  const { $path, $query, $activeRoutes } = useUnit({
    $path: router.$path,
    $query: router.$query,
    $activeRoutes: router.$activeRoutes,
  });
}

When to use:

  • Use useRouter() - for most cases (automatically bound values)
  • Use useRouterContext() - when you need raw stores for custom Effector patterns or selective binding

Released under the MIT License.