Skip to content

Commit

Permalink
[react-router-dom] Add missing functions from tutorial (#4433)
Browse files Browse the repository at this point in the history
* add missing types

* correct definition

* add tests

* add missing useRouteError

* add missing useLoaderData
  • Loading branch information
Brianzchen committed Apr 16, 2023
1 parent 8beebb1 commit 86f8b7e
Show file tree
Hide file tree
Showing 2 changed files with 120 additions and 0 deletions.
Expand Up @@ -8,6 +8,14 @@ declare module 'react-router-dom' {
// `@remix-run/router` /
// ----------------------------------/

declare type FutureConfig = {|
v7_normalizeFormMethod: boolean,
|};

declare type RouteData = {|
[routeId: string]: any,
|};

declare type To = LocationShape | string;

declare export type Location = $ReadOnly<{
Expand Down Expand Up @@ -382,10 +390,46 @@ declare module 'react-router-dom' {
handle: Handle,
|}>;

/**
* Returns the nearest ancestor Route error, which could be a loader/action
* error or a render error. This is intended to be called from your
* ErrorBoundary/errorElement to display a proper error message.
*/
declare export function useRouteError(): any;

/**
* Returns the loader data for the nearest ancestor Route loader
*/
declare export function useLoaderData(): any;

declare export type RouterProviderProps = {|
fallbackElement?: React$Node;
router: typeof Router;
|}

declare export function RouterProvider(RouterProviderProps): React$Node;

// ----------------------------------/
// `react-router-dom` /
// ----------------------------------/

declare type DOMRouterOpts = {|
basename?: string,
future?: FutureConfig,
hydrationData?: {|
loaderData?: RouteData,
actionData?: RouteData | null,
errors?: RouteData | null,
|},
// Should be Window type but flow doesn't have this
window?: any,
|};

declare export function createBrowserRouter(
routes: Array<RouteObject>,
opts?: DOMRouterOpts
): typeof Router;

declare type URLSearchParamsInit =
| string
| Array<[string, string]>
Expand Down
@@ -1,6 +1,8 @@
// @flow
import React from 'react';
import {
createBrowserRouter,
RouterProvider,
BrowserRouter,
HashRouter,
Link,
Expand All @@ -21,6 +23,8 @@ import {
useParams,
useRouteMatch,
useMatches,
useRouteError,
useLoaderData,
} from 'react-router-dom';
import type {
AgnosticRouteMatch,
Expand Down Expand Up @@ -403,10 +407,82 @@ describe('react-router-dom', () => {
});
});

describe('useRouteError', () => {
// It is described as any in the type def, but unknown the actual library
(useRouteError(): string);

// $FlowExpectedError[extra-arg] it takes no args
useRouteError('test');
});

describe('useLoaderData', () => {
// It is described as any in the type def, but unknown the actual library
(useLoaderData(): string);

// $FlowExpectedError[extra-arg] it takes no args
useLoaderData('test');
});

// ----------------------------------/
// `react-router-dom` /
// ----------------------------------/

describe('RouterProvider use case', () => {
it('works', () => {
const router = createBrowserRouter([
{
path: "/",
element: <div>Hello world!</div>,
},
]);

(() => (
<RouterProvider router={router} />
))
});

it('catches createBrowserRouter error usages', () => {
// $FlowExpectedError[incompatible-call]
createBrowserRouter();
// $FlowExpectedError[incompatible-cast]
(createBrowserRouter([]): string);
// $FlowExpectedError[incompatible-call]
createBrowserRouter('test');

createBrowserRouter([], {});
createBrowserRouter([], {
basename: 'test',
future: {
v7_normalizeFormMethod: true,
},
hydrationData: {
loaderData: { a: 1 },
actionData: { a: 1 },
errors: null,
},
window: {},
});

createBrowserRouter([], {
// $FlowExpectedError[incompatible-call]
basename: 1,
});
// $FlowExpectedError[prop-missing]
createBrowserRouter([], {
// $FlowExpectedError[prop-missing]
future: {
a: 1,
},
});
createBrowserRouter([], {
hydrationData: {
// $FlowExpectedError[incompatible-call]
loaderData: null,
},
});
});
});

describe('BrowserRouter', () => {
it('works', () => {
<BrowserRouter>
Expand Down

0 comments on commit 86f8b7e

Please sign in to comment.