Last active
December 3, 2019 23:47
-
-
Save alexeyraspopov/2620009100a96829c3b427f453e4e333 to your computer and use it in GitHub Desktop.
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
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