fix: 🐛 make useLocation work on server, improve hook

This commit is contained in:
streamich 2019-04-09 15:49:49 +02:00
parent 5bd194f23a
commit 6f6030a75e
2 changed files with 51 additions and 49 deletions

View File

@ -3,13 +3,19 @@ import {storiesOf} from '@storybook/react';
import {useLocation} from '..';
import ShowDocs from './util/ShowDocs';
const go = (page) => history.pushState({}, '', page);
const Demo = () => {
const state = useLocation();
return (
<pre>
{JSON.stringify(state, null, 2)}
</pre>
<div>
<button onClick={() => go('page-1')}>Page 1</button>
<button onClick={() => go('page-2')}>Page 2</button>
<pre>
{JSON.stringify(state, null, 2)}
</pre>
</div>
);
};

View File

@ -36,57 +36,53 @@ export interface LocationSensorState {
search?: string;
}
const useLocation = (): LocationSensorState => {
const buildState = (trigger: string) => {
const {
state,
length
} = history;
const useLocationServer = (): LocationSensorState => ({
trigger: 'load',
length: 1,
});
const {
hash,
host,
hostname,
href,
origin,
pathname,
port,
protocol,
search
} = location;
const buildState = (trigger: string) => {
const {
state,
length
} = history;
return {
trigger,
state,
length,
hash,
host,
hostname,
href,
origin,
pathname,
port,
protocol,
search
};
const {
hash,
host,
hostname,
href,
origin,
pathname,
port,
protocol,
search
} = location;
return {
trigger,
state,
length,
hash,
host,
hostname,
href,
origin,
pathname,
port,
protocol,
search
};
};
const [state, setState] = useState(isClient
? buildState('load')
: {
trigger: 'load',
length: 1
}
);
const onChange = (trigger: string) =>
setState(buildState(trigger));
const onPopstate = () => onChange('popstate');
const onPushstate = () => onChange('pushstate');
const onReplacestate = () => onChange('replacestate');
const useLocationBrowser = (): LocationSensorState => {
const [state, setState] = useState(buildState('load'));;
useEffect(() => {
const onPopstate = () => setState(buildState('popstate'));
const onPushstate = () => setState(buildState('pushstate'));
const onReplacestate = () => setState(buildState('replacestate'));
on(window, 'popstate', onPopstate);
on(window, 'pushstate', onPushstate);
on(window, 'replacestate', onReplacestate);
@ -101,4 +97,4 @@ const useLocation = (): LocationSensorState => {
return state;
};
export default useLocation;
export default isClient ? useLocationBrowser : useLocationServer;