Created
August 23, 2018 18:25
-
-
Save mminer/ad4e8cc8e5f272a180219ce69b0abecb to your computer and use it in GitHub Desktop.
React higher-order component that provides basic hash-based routing.
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
// Usage: | |
// | |
// const YourComponent = ({ activePageHash }) => ... | |
// export default withHashRouter(YourComponent, ['#valid-page-1', '#valid-page-2']); | |
import { Component, createElement as h } from 'react'; | |
// Falls back to the initial page if the hash specifies an unknown one. | |
function replaceHashWithValidPage(validPageHashes) { | |
if (!validPageHashes) { | |
return; | |
} | |
const { hash, pathname } = location; | |
if (validPageHashes.includes(hash)) { | |
return; | |
} | |
// Changing location.hash directly causes onhashchange to fire, which is | |
// undesirable when calling this function from our hashchange handler. | |
history.replaceState(null, null, pathname + validPageHashes[0]); | |
} | |
export default function withHashRouter(WrappedComponent, validPageHashes) { | |
return class HashRouter extends Component { | |
constructor(props) { | |
super(props); | |
replaceHashWithValidPage(validPageHashes); | |
this.handleHashChange = this.handleHashChange.bind(this); | |
this.state = { activePageHash: location.hash }; | |
} | |
componentDidMount() { | |
window.addEventListener('hashchange', this.handleHashChange); | |
} | |
componentWillUnmount() { | |
window.removeEventListener('hashchange', this.handleHashChange); | |
} | |
render() { | |
return h(WrappedComponent, { | |
activePageHash: this.state.activePageHash, | |
}); | |
} | |
handleHashChange() { | |
replaceHashWithValidPage(validPageHashes); | |
if (location.hash === this.state.activePageHash) { | |
return; | |
} | |
this.setState({ activePageHash: location.hash }); | |
} | |
}; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment