Custom React Router
Last active
September 3, 2020 23:49
-
-
Save GGrassiant/d0045bb0dc6d833be0f95edce2fbdd55 to your computer and use it in GitHub Desktop.
Custom React Router
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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> | |
); | |
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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'); | |
// }); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import React from 'react'; | |
const Link = ({ className, href, children }) => { | |
const onClick = (event) => { | |
// handle ctrl or command key for target blank | |
if (event.metaKey || event.ctrlKey) { | |
return; | |
} | |
event.preventDefault(); // avoiding a reload of the page | |
window.history.pushState({}, '', href); // adding the desired route to the history | |
// dispatching a pathname change to all Route components | |
// listening to the url | |
const navEvent = new PopStateEvent('popstate'); | |
window.dispatchEvent(navEvent); | |
}; | |
return ( | |
<a onClick={onClick} className={className} href={href}> | |
{children} | |
</a> | |
); | |
}; | |
export default Link; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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