Last active
March 26, 2019 18:32
-
-
Save brigand/ea726f15f56b736077cff8f9df7928ff to your computer and use it in GitHub Desktop.
The `useLocationState` hook gives a `React.useState`-like interface to updating the HTML5 History API location state.
This file contains hidden or 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
function Foo() { | |
const [count, setCount] = useLocationState('Foo', 0); | |
return ( | |
<div> | |
<button onClick={() => setCount(c => c + 1)}>Clicks: {count}</button> | |
<button onClick={() => setCount(0)}>Reset</button> | |
</div> | |
); | |
} |
This file contains hidden or 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 * as React from 'react'; | |
import { createBrowserHistory } from 'history'; | |
const history = createBrowserHistory(); | |
export function useHistory() { | |
return history; | |
} | |
export function useLocationState<T>( | |
key: ?string, | |
initial: T, | |
): [T, (update: T | ((x: T) => T)) => void] { | |
const stateKey = key || '_default'; | |
const [loc, setLoc] = React.useState({ | |
pathname: window.location.pathname, | |
search: window.location.search, | |
hash: window.location.hash, | |
state: window.history.state && window.history.state.state, | |
}); | |
const get = () => { | |
if (loc.state && loc.state[stateKey] !== undefined) { | |
return loc.state[stateKey]; | |
} | |
return initial; | |
}; | |
React.useEffect( | |
() => | |
history.listen((location) => { | |
setLoc(location); | |
}), | |
[], | |
); | |
const set = React.useCallback( | |
(update, callback) => { | |
const state = typeof update === 'function' ? update(get()) : update; | |
history.replace({ | |
...loc, | |
state: { | |
...loc.state, | |
[stateKey]: state, | |
}, | |
}); | |
}, | |
[loc], | |
); | |
return [get(), set]; | |
} | |
export default history; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment