Skip to content

Instantly share code, notes, and snippets.

@alexeyraspopov
Last active December 3, 2019 23:47
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save alexeyraspopov/2620009100a96829c3b427f453e4e333 to your computer and use it in GitHub Desktop.
Save alexeyraspopov/2620009100a96829c3b427f453e4e333 to your computer and use it in GitHub Desktop.
import { useState, useCallback } from 'react';
let defaultHandler = {
read(defaults) {
return getInitialParams(defaults, window.location.search);
},
write(state) {
let params = getUpdatedParams(state);
window.history.pushState(null, null, '?' + params.toString());
},
};
export function useQueryState(defaults, handler = defaultHandler) {
let [state, setState] = useState(() => handler.read(defaults));
let updateState = useCallback(patch => {
setState(state => {
let newState = Object.assign({}, state, patch);
handler.write(newState);
return newState;
});
}, [handler]);
return [state, updateState];
}
function getInitialParams(defaults, search) {
let params = new URLSearchParams(search);
return Object.keys(defaults).reduce((a, k) => {
let value = params.has(k) ? params.get(k) : defaults[k];
return Object.assign(a, { [k]: value });
}, {});
}
function getUpdatedParams(state) {
return Object.keys(state).reduce((p, k) => {
let v = state[k];
if (v !== null) {
p.append(k, v);
}
return p;
}, new URLSearchParams());
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment