Skip to content

Instantly share code, notes, and snippets.

@GGrassiant
Last active September 3, 2020 23:49
Show Gist options
  • Save GGrassiant/d0045bb0dc6d833be0f95edce2fbdd55 to your computer and use it in GitHub Desktop.
Save GGrassiant/d0045bb0dc6d833be0f95edce2fbdd55 to your computer and use it in GitHub Desktop.
Custom React Router
import React, { useState } from 'react';
import Accordion from './components/Accordion';
import Search from './components/Search';
import Dropdown from './components/Dropdown';
import Translate from './components/Translate';
import Route from './components/Route';
import Header from './components/Header';
const items = [
{
title: 'What is React?',
content: 'React is a front end javascript framework',
},
{
title: 'Why use React?',
content: 'React is a favorite JS library among engineers',
},
{
title: 'How do you use React?',
content: 'You use React by creating components',
},
];
const options = [
{
label: 'The Color Red',
value: 'red',
},
{
label: 'The Color Green',
value: 'green',
},
{
label: 'A Shade of Blue',
value: 'blue',
},
];
export default () => {
const [selected, setSelected] = useState(options[0]);
return (
<div>
<Header />
<Route path="/">
<Accordion items={items} />
</Route>
<Route path="/list">
<Search />
</Route>
<Route path="/dropdown">
<Dropdown
label="Select a color"
options={options}
selected={selected}
onSelectedChange={setSelected}
/>
</Route>
<Route path="/translate">
<Translate />
</Route>
</div>
);
};
import React, { Component } from 'react';
const asyncComponent = (importComponent) => {
return class extends Component {
state = {
component: null
}
componentDidMount () {
importComponent()
.then(cmp => {
this.setState({component: cmp.default});
});
}
render () {
const C = this.state.component;
return C ? <C {...this.props} /> : null;
}
}
}
export default asyncComponent;
// Component
// const AsyncNewPost = asyncComponent(() => {
// return import('./NewPost/NewPost');
// });
import React from 'react';
import Link from './Link';
const Header = () => {
return (
<div className="ui secondary pointing menu">
<Link href="/" className="item">
Accordion
</Link>
<Link href="/list" className="item">
Search
</Link>
<Link href="/dropdown" className="item">
Dropdown
</Link>
<Link href="/translate" className="item">
Translate
</Link>
</div>
);
};
export default Header;
// Libs
import React, { Suspense } from 'react';
import { renderRoutes } from 'react-router-config';
// components
import Alert from '../Alert/Alert';
import ErrorBoundary from '../../utils/ErrorBoundary';
import Loader from '../Loader/Loader';
import NavBar from '../NavBar/NavBar';
// Utils
import { localizeRoutes } from '../../services/i18n/utils';
const Layout = (props: any) => {
const { route } = props;
return (
<>
<NavBar />
<Alert message="actionFailed" visible={false} />
<ErrorBoundary>
<Suspense fallback={<Loader />}>
{renderRoutes(localizeRoutes(route.routes))}
</Suspense>
</ErrorBoundary>
</>
);
};
export default Layout;
import { useEffect, useState } from 'react';
const Route = ({ path, children }) => {
// Current path name
const [currentPath, setCurrentPath] = useState(window.location.pathname);
useEffect(() => {
const onLocationChange = () => {
setCurrentPath(window.location.pathname);
};
// Listen to changes in the pathname
// to re-render and check the currentPath
window.addEventListener('popstate', onLocationChange);
return () => {
window.removeEventListener('popstate', onLocationChange);
};
}, []);
// Render the right component when the pathname changes
return currentPath === path ? children : null;
};
export default Route;
// Libs
import React, { lazy } from 'react';
import { Redirect } from 'react-router-dom';
// components
import Layout from '../components/Layout/Layout';
import Error from '../utils/Error';
// Utils
import { defaultLocale } from '../services/config/i18n';
const routes = [
{
path: '/',
exact: true,
localize: false,
component: () => <Redirect to={`${defaultLocale}/home`} />,
},
{
route: '*',
component: Layout,
routes: [
{
path: '/home',
exact: true,
component: lazy(() => import('../pages/HomePage/HomePage')),
},
{
path: '/form-page',
exact: true,
component: lazy(() => import('../pages/FormPage/FormPage')),
},
{
path: '/form-page/:itemId',
exact: true,
component: lazy(() => import('../pages/FormPage/FormPage')),
},
{
component: () => <Error />,
},
],
},
];
export default routes;
// in index.jsx
// const Routes = () => renderRoutes(routes);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment