Navigation Menu

Skip to content

Instantly share code, notes, and snippets.

@mjackson
Created April 12, 2018 01:12
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mjackson/d054bdc3048f5bd9d7f64bcb9a64f709 to your computer and use it in GitHub Desktop.
Save mjackson/d054bdc3048f5bd9d7f64bcb9a64f709 to your computer and use it in GitHub Desktop.
import React from "react";
import pathToRegexp from "path-to-regexp";
function Home() {
return <h1>Home</h1>;
}
function About() {
return <h1>About</h1>;
}
function Contact() {
return <h1>Contact</h1>;
}
function Inbox({ match, params }) {
return (
<div>
<h1>Inbox</h1>
<Message key={params.id}/>
<div>
{params.id ? <p>Now showing message {params.id}</p> : null}
</div>
</div>
);
}
const RoutingContext = React.createContext();
class Router extends React.Component {
state = {
location: window.location
};
push = url => {
window.history.pushState(null, null, url);
this.setState({ location: window.location });
};
handlePopState = () => {
this.setState({ location: window.location });
};
componentDidMount() {
window.addEventListener("popstate", this.handlePopState);
}
componentWillUnmount() {
window.removeEventListener("popstate", this.handlePopState);
}
render() {
const { location } = this.state;
return (
<RoutingContext.Provider
{...this.props}
value={{ location, push: this.push }}
/>
);
}
}
function Route({ path, component: Component }) {
const keys = [];
const regexp = pathToRegexp(path, keys);
return (
<RoutingContext.Consumer>
{({ location }) => {
const match = regexp.exec(location.pathname);
if (match) {
const params = keys.reduce((memo, key, index) => {
memo[key.name] = match[index + 1];
return memo;
}, {});
return <Component match={match} params={params} />;
}
return null;
}}
</RoutingContext.Consumer>
);
}
function Link(props) {
const { to, ...anchorProps } = props;
return (
<RoutingContext.Consumer>
{({ push }) => (
<a
{...anchorProps}
href={to}
onClick={event => {
event.preventDefault();
push(to);
}}
/>
)}
</RoutingContext.Consumer>
);
}
class App extends React.Component {
render() {
return (
<Router>
<div>
<h1>Welcome to the app!</h1>
<nav>
<ul>
<li>
<Link to="/about">About Us</Link>
</li>
<li>
<Link to="/contact">Contact Us</Link>
</li>
<li>
<Link to="/">Home</Link>
</li>
</ul>
</nav>
<Redirect to="..."/>
<Route path="/about" component={About} />
<Route path="/contact" component={Contact} />
<ParentRoute path="/" component={Home} />
</div>
</Router>
);
}
}
export default App;
@anosikeosifo
Copy link

Thanks for sharing! @mjackson

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment