refactor Router

This commit is contained in:
Ruidy 2021-03-28 13:45:44 +02:00
parent d267c55323
commit 8fb5ca872c
13 changed files with 106 additions and 141 deletions

View file

@ -1,17 +1,16 @@
import React, {FC, useState} from "react";
import { Router } from "./utils/router";
import React, { FC, useState } from "react";
import { Router } from "./router/Router";
import { PreLoader } from "./components/PreLoader";
import { useAuth0 } from "./utils/auth0-spa";
import { getData } from "./utils/methods";
import history from "./utils/history";
import "./index.css";
import MainLayout from "./layouts/MainLayout";
import MainRouter from "./controllers/MainRouter";
import { AppRouter } from "./router";
export const App:FC = () => {
export const App: FC = () => {
const { loading } = useAuth0();
const [searchString, setSearchString] = useState("");
const [searchResults, setSearchResults] = useState({ meals: [] });
@ -96,7 +95,6 @@ export const App:FC = () => {
const handleChange = (e) => {
const { value } = e.target;
setSearchString(value);
};
return loading ? (
@ -104,7 +102,7 @@ export const App:FC = () => {
<PreLoader />
</div>
) : (
<Router >
<Router>
<MainLayout
buttonUrl={buttonUrl}
// meal={meal}
@ -117,7 +115,7 @@ export const App:FC = () => {
setSearchString={setSearchString}
getSearchResults={getSearchResults}
>
<MainRouter
<AppRouter
buttonUrl={buttonUrl}
meal={meal}
getMeal={getMeal}

View file

@ -1,75 +0,0 @@
import React from "react";
import { Switch, Route, Redirect } from "react-router-dom";
import { SearchController } from "./SearchController";
import { HomeController } from "./HomeController";
import { MealController } from "./MealController";
import { CategoryController } from "./CategoryController";
import { CategoryListController } from "./CategoryListController";
import { ProfileController } from "./ProfileController";
import { ContactPage } from "../pages/Contact";
import { NotFoundPage } from "../pages/NotFoundPage";
import { PrivateRoute } from "../components/PrivateRoute";
const MainRouter = ({
buttonUrl,
meal,
getMeal,
getRandomMeal,
searchString,
searchResults,
}) => {
return (
<Switch>
<Route exact path="/">
<HomeController buttonUrl={buttonUrl} />
</Route>
<PrivateRoute exact path="/profile" component={ProfileController} />
<Route exact path={buttonUrl}>
<MealController
meal={meal}
getMeal={getMeal}
getRandomMeal={getRandomMeal}
/>
</Route>
<Route exact path="/categories">
<CategoryListController />
</Route>
<Route path="/categories/:strCategory/">
<CategoryController />
</Route>
<Route exact path="/search">
<SearchController
searchString={searchString}
searchResults={searchResults}
/>
</Route>
<Route path="/contact">
<ContactPage />
</Route>
<Route path="/404">
<NotFoundPage handleClick={getRandomMeal} />
</Route>
<Route path="/:id">
<MealController
meal={meal}
getMeal={getMeal}
getRandomMeal={getRandomMeal}
/>
</Route>
<Route path="*">
<Redirect to="/404" />
</Route>
</Switch>
);
};
export default MainRouter;

74
src/router/AppRouter.tsx Normal file
View file

@ -0,0 +1,74 @@
import { Switch, Route, Redirect } from "react-router-dom";
import { SearchController } from "../containers/SearchController";
import { HomeController } from "../containers/HomeController";
import { MealController } from "../containers/MealController";
import { CategoryController } from "../containers/CategoryController";
import { CategoryListController } from "../containers/CategoryListController";
import { ProfileController } from "../containers/ProfileController";
import { ContactPage } from "../pages/Contact";
import { NotFoundPage } from "../pages/NotFoundPage";
import { PrivateRoute } from "./PrivateRoute";
//TODO: remove state from router move to containers
const AppRouter = ({
buttonUrl,
meal,
getMeal,
getRandomMeal,
searchString,
searchResults,
}) => (
<Switch>
<Route exact path="/">
<HomeController buttonUrl={buttonUrl} />
</Route>
<PrivateRoute exact path="/profile" component={ProfileController} />
<Route exact path={buttonUrl}>
<MealController
meal={meal}
getMeal={getMeal}
getRandomMeal={getRandomMeal}
/>
</Route>
<Route exact path="/categories">
<CategoryListController />
</Route>
<Route path="/categories/:strCategory/">
<CategoryController />
</Route>
<Route exact path="/search">
<SearchController
searchString={searchString}
searchResults={searchResults}
/>
</Route>
<Route path="/contact">
<ContactPage />
</Route>
<Route path="/404">
<NotFoundPage handleClick={getRandomMeal} />
</Route>
<Route path="/:id">
<MealController
meal={meal}
getMeal={getMeal}
getRandomMeal={getRandomMeal}
/>
</Route>
<Route path="*">
<Redirect to="/404" />
</Route>
</Switch>
);
export default AppRouter;

View file

@ -1,25 +1,24 @@
import React, { useEffect } from "react";
import { useEffect } from "react";
import { Route } from "react-router-dom";
import { useAuth0 } from "../utils/auth0-spa";
// TODO use FC and props
export const PrivateRoute = ({ component: Component, path, ...rest }) => {
const { loading, isAuthenticated, loginWithRedirect } = useAuth0();
useEffect(() => {
// catches infinite loading when no user is logged in
if (loading || isAuthenticated) {
// catches infinite loading when no user is logged in
return;
}
const fn = async () => {
const fn = async () =>
await loginWithRedirect({
appState: { targetUrl: path }
appState: { targetUrl: path },
});
};
fn();
}, [loading, isAuthenticated, loginWithRedirect, path]);
const render = props =>
isAuthenticated === true ? <Component {...props} /> : null;
const render = (props) => (isAuthenticated ? <Component {...props} /> : null);
return <Route path={path} render={render} {...rest} />;
};

18
src/router/Router.tsx Normal file
View file

@ -0,0 +1,18 @@
import { FC, useEffect } from "react";
import { Router as RouterOriginal, useLocation } from "react-router-dom";
import history from "../utils/history";
export const Router: FC = ({ children }) => (
<RouterOriginal history={history}>
<ScrollToTop />
{children}
</RouterOriginal>
);
export const ScrollToTop: FC = () => {
const location = useLocation();
useEffect(() => {
window.scrollTo(0, 0);
}, [location.pathname]);
return null;
};

2
src/router/index.ts Normal file
View file

@ -0,0 +1,2 @@
import AppRouter from "./AppRouter";
export { AppRouter };

View file

@ -1,51 +0,0 @@
import React, { useMemo, useEffect } from "react";
import {
Router as RouterOriginal,
useParams,
useLocation,
useHistory,
useRouteMatch
} from "react-router-dom";
import queryString from "query-string";
import { createBrowserHistory } from "history";
export const history = createBrowserHistory();
export const Router = ({ children }) => {
return (
<RouterOriginal history={history}>
<ScrollToTop />
{children}
</RouterOriginal>
);
};
export const ScrollToTop = () => {
const location = useLocation();
useEffect(() => {
window.scrollTo(0, 0);
}, [location.pathname]);
return null;
};
export const useRouter = () => {
const params = useParams();
const location = useLocation();
const history = useHistory();
const match = useRouteMatch();
return useMemo(() => {
return {
push: history.push,
replace: history.replace,
pathname: location.pathname,
query: {
...queryString.parse(location.search),
...params
},
match,
location,
history
};
}, [params, match, location, history]);
};