Skip to content

Commit

Permalink
feat: add Redirect component
Browse files Browse the repository at this point in the history
fix #2
  • Loading branch information
uhyo committed Oct 17, 2020
1 parent eaebe20 commit 7778f9a
Show file tree
Hide file tree
Showing 2 changed files with 71 additions and 0 deletions.
49 changes: 49 additions & 0 deletions src/react/components/Redirect.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import { createMemoryHistory } from "history";
import React, { useEffect, useState } from "react";
import { useRoutes } from "../hooks/useRoutes";
import { Path } from "../shorthand";
import { renderInHistory, screen } from "../test-utils";
import { Redirect } from "./Redirect";

describe("Redirect", () => {
it("changes path on rendering", async () => {
const history = createMemoryHistory({
initialEntries: [
{
pathname: "/foo",
state: null,
},
],
});
const Foo: React.FC = () => {
const [redirect, setRedirect] = useState(false);
useEffect(() => {
setTimeout(() => setRedirect(true), 100);
}, []);
return redirect ? (
<Redirect route={routes._.bar} />
) : (
<div>Redirecting...</div>
);
};
const routes = Path()
.route("foo", (foo) =>
foo.action(() => {
return <Foo />;
})
)
.route("bar", (bar) => bar.action(() => <div>I AM BAR</div>));
const Component: React.FC = () => {
const contents = useRoutes(routes);
return contents;
};

renderInHistory(history, <Component />);
expect(await screen.findByText("I AM BAR")).toBeInTheDocument();
expect(history.index).toBe(0);
expect(history.location).toMatchObject({
pathname: "/bar",
state: null,
});
});
});
22 changes: 22 additions & 0 deletions src/react/components/Redirect.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { useLayoutEffect } from "react";
import { useNavigate } from "../hooks/useNavigate";
import { ReactRouteRecord } from "../types/ReactElement";

export type RedirectProps<Match> = {
route: ReactRouteRecord<Match>;
} & ({} extends Match ? { match?: Match } : { match: Match });

/**
* Redirects to given route.
*/
export const Redirect = <Match,>({
route,
match,
}: RedirectProps<Match>): null => {
const navigate = useNavigate();
useLayoutEffect(() => {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
(navigate.replace as any)(route, match);
});
return null;
};

0 comments on commit 7778f9a

Please sign in to comment.