JSPM

@remix-run/router

0.1.0
  • ESM via JSPM
  • ES Module Entrypoint
  • Export Map
  • Keywords
  • License
  • Repository URL
  • TypeScript Types
  • README
  • Created
  • Published
  • Downloads 10244932
  • Score
    100M100P100Q225041F
  • License MIT

Nested/Data-driven/Framework-agnostic Routing

Package Exports

  • @remix-run/router
  • @remix-run/router/index.js
  • @remix-run/router/main.js

This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (@remix-run/router) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.

Readme

Router

The @remix-run/router package is the heart of React Router and provides all the core functionality for routing, data loading, data mutations, and navigation.

If you're using React Router, you should never import anything directly from the @remix-run/router or react-router packages, but you should have everything you need in either react-router-dom or react-router-native. Both of those packages re-export everything from @remix-run/router and react-router.

API

A Router instance can be created using createRouter:

let router = createRouter({
  // Routes array using react-router RouteObject's
  routes,
  // History instance
  history,
  // Callback function executed on every state change
  onChange: (state) => { ... },
  // Optional hydration data for SSR apps
  hydrationData?: HydrationState;
}

Internally, the Router represents the state in an object of the following format, which is available through router.state or via the onChange callback function:

interface RouterState {
  // The `history` action of the most recently completed navigation
  action: Action;
  // The current location of the router.  During a navigation this reflects
  // the "old" location and is updated upon completion of the navigation
  location: Location;
  // The current set of route matches
  matches: RouteMatch[];
  // The state of the current navigation
  navigation: Navigation;
  // Data from the loaders for the current matches
  loaderData: RouteData;
  // Data from the action for the current matches
  actionData: RouteData | null;
  // Errors thrown from loaders/actions for the current matches
  errors: RouteData | null;
}

All navigations are done through the router.navigate API which is overloaded to support different types of navigations:

// Link navigation (pushes onto the history stack by default)
router.navigate('/page');

// Link navigation (replacing the history stack)
router.navigate('/page', { replace: true });

// Pop navigation (moving backward/forward in the history stack)
router.navigate(-1);

// Form navigation
router.navigate('/page', {
  formMethod: 'GET',
  formData: new FormData(...),
});

Each navigation (link click or form submission) in the Router is reflected via an internal state.navigation that indicates the state of the navigation. This concept of a navigation is a complex and heavily async bit of logic that is foundational to the Router's ability to manage data loading, submission, error handling, redirects, interruptions, and so on. Due to the user-driven nature of interruptions we don't quite believe it can be modeled as a finite state machine, however we have modeled some of the happy path flows below for clarity.

Note: This does not depict error or interruption flows.

graph LR
  %% Link click
  idle -->|link clicked| loading/normalLoad
  subgraph "<Link> click"
  loading/normalLoad -->|loader redirected| loading/normalRedirect
  loading/normalRedirect --> loading/normalRedirect
  end
  loading/normalLoad -->|loaders completed| idle
  loading/normalRedirect -->|loaders completed| idle

  %% Form method=get
  idle -->|form method=get| submitting/loaderSubmission
  subgraph "<Form method=get>"
  submitting/loaderSubmission -->|loader redirected| R1[loading/submissionRedirect]
  R1[loading/submissionRedirect] --> R1[loading/submissionRedirect]
  end
  submitting/loaderSubmission -->|loaders completed| idle
  R1[loading/submissionRedirect] -->|loaders completed| idle

  %% Form method=post
  idle -->|form method=post| submitting/actionSubmission
  subgraph "<Form method=post>"
  submitting/actionSubmission -->|action returned| loading/actionReload
  submitting/actionSubmission -->|action redirected| R2[loading/submissionRedirect]
  loading/actionReload -->|loader redirected| R2[loading/submissionRedirect]
  R2[loading/submissionRedirect] --> R2[loading/submissionRedirect]
  end
  loading/actionReload -->|loaders completed| idle
  R2[loading/submissionRedirect] -->|loaders completed| idle

  idle -->|fetcher action redirect| R3[loading/submissionRedirect]
  subgraph "Fetcher action redirect"
  R3[loading/submissionRedirect] --> R3[loading/submissionRedirect]
  end
  R3[loading/submissionRedirect] -->|loaders completed| idle

Fetcher Flows

Fetcher submissions and loads in the Router can each have their own internal states, indicated on fetcher.state and fetcher.type. As with navigations, these states are a complex and heavily async bit of logic that is foundational to the Router's ability to manage data loading, submission, error handling, redirects, interruptions, and so on. Due to the user-driven nature of interruptions we don't quite believe it can be modeled as a finite state machine, however we have modeled some of the happy path flows below for clarity.

Note: This does not depict error or interruption flows, nor the ability to re-use fetchers once they've reached idle/done.

graph LR
  idle/init -->|"load"| loading/normalLoad
  subgraph "Normal Fetch"
  loading/normalLoad -.->|loader redirected| T1{{navigation}}
  end
  loading/normalLoad -->|loader completed| idle/done
  T1{{navigation}} -.-> idle/done

  idle/init -->|"submit (get)"| submitting/loaderSubmission
  subgraph "Loader Submission"
  submitting/loaderSubmission -.->|"loader redirected"| T2{{navigation}}
  end
  submitting/loaderSubmission -->|loader completed| idle/done
  T2{{navigation}} -.-> idle/done

  idle/init -->|"submit (post)"| submitting/actionSubmission
  subgraph "Action Submission"
  submitting/actionSubmission -->|action completed| loading/actionReload
  submitting/actionSubmission -->|action redirected| loading/submissionRedirect
  loading/submissionRedirect -.-> T3{{navigation}}
  loading/actionReload -.-> |loaders redirected| T3{{navigation}}
  end
  T3{{navigation}} -.-> idle/done
  loading/actionReload --> |loaders completed| idle/done

  idle/done -->|"revalidate"| loading/revalidate
  subgraph "Fetcher Revalidation"
  loading/revalidate -.->|loader redirected| T4{{navigation}}
  end
  loading/revalidate -->|loader completed| idle/done
  T4{{navigation}} -.-> idle/done

  classDef navigation fill:lightgreen;
  class T1,T2,T3,T4 navigation;