Skip to content

Instantly share code, notes, and snippets.

@lenkan
Created March 2, 2019 18:26
Show Gist options
  • Select an option

  • Save lenkan/357b006dd31a8c78f659430467369ea7 to your computer and use it in GitHub Desktop.

Select an option

Save lenkan/357b006dd31a8c78f659430467369ea7 to your computer and use it in GitHub Desktop.
React hook that keeps up to date with the current location.
// @ts-check
import { useState, useEffect } from 'react'
function getCurrentLocation () {
return {
pathname: window.location.pathname,
search: window.location.search
}
}
/**
* @type {Array<() => void>}
*/
const listeners = []
/**
* Notifies all location listeners. Can be used if the history state has been manipulated
* in by another module. Effectifely, all components using the 'useLocation' hook will
* update.
*/
export function notify () {
listeners.forEach(listener => listener())
}
export function useLocation () {
const [{ pathname, search }, setLocation] = useState(getCurrentLocation())
useEffect(() => {
window.addEventListener('popstate', handleChange)
return () => window.removeEventListener('popstate', handleChange)
}, [])
useEffect(() => {
listeners.push(handleChange)
return () => listeners.splice(listeners.indexOf(handleChange), 1)
}, [])
function handleChange () {
setLocation(getCurrentLocation())
}
/**
* @param {string} url
*/
function push (url) {
window.history.pushState(null, null, url)
notify()
}
/**
* @param {string} url
*/
function replace (url) {
window.history.replaceState(null, null, url)
notify()
}
return {
push,
replace,
pathname,
search
}
}
@lenkan

lenkan commented Apr 1, 2020

Copy link
Copy Markdown
Author

Hi @paulmelnikow. No it does not.

@paulmelnikow

Copy link
Copy Markdown

Do you mean that it's in the public domain?

@chmartinez

Copy link
Copy Markdown

You should makes this an npm package! Thanks!

@f-bog

f-bog commented Nov 16, 2023

Copy link
Copy Markdown

Using this with preact, some really awesome stuff. Thanks.

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