Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
(newValue, opts) => {
// stringify the given value (or array of strings)
let newQueryStateValue = toQueryStateValue(newValue)
// warn when value type is not supported (do not warn when null was passed explicitly)
if (
(newQueryStateValue === null && newValue !== newQueryStateValue) ||
!(
newQueryStateValue !== null &&
typeof parseQueryStateValue(newQueryStateValue, defaultValue) === typeof defaultValue
)
) {
console.warn(
'value of ' +
JSON.stringify(newValue) +
' is not supported. "' +
itemName +
'" will reset to default value',
defaultValue
)
newQueryStateValue = null
}
// when new value is equal to default, we call setQueryState with a null value to reset query string
// arrays have to be compared json stringified, other values can compared by value
if (Array.isArray(defaultValue) && sameAsJsonString(newValue, defaultValue)) {
(newValue, opts) => {
// stringify the given value (or array of strings)
let newQueryStateValue = toQueryStateValue(newValue)
// warn when value type is not supported (do not warn when null was passed explicitly)
if (
(newQueryStateValue === null && newValue !== newQueryStateValue) ||
!(
newQueryStateValue !== null &&
typeof parseQueryStateValue(newQueryStateValue, defaultValue) === typeof defaultValue
)
) {
console.warn(
'value of ' +
JSON.stringify(newValue) +
' is not supported. "' +
itemName +
'" will reset to default value',
defaultValue
const stripOverwrite: QueryStateMerge = {}
// when a params are set to the same value as in the defaults
// we remove them to avoid having two URLs reproducing the same state unless stripDefaults === false
if (stripDefaults) {
Object.entries(newState).forEach(([key]) => {
if (defaultQueryState[key] === newState[key]) {
stripOverwrite[key] = null
}
})
}
// retrieve the last value (by re-executing the search getter)
const currentQueryState: QueryState = {
...defaultQueryState,
...parseQueryState(activeQSI.getQueryString()),
}
const mergedQueryString = createMergedQuery(currentQueryState || {}, newState, stripOverwrite)
activeQSI.setQueryString(mergedQueryString, opts || {})
// triggers an update (in case the QueryStringInterface misses to do so)
setLatestMergedQueryString(mergedQueryString)
}, [])
} else if (newValue === defaultValue) {
newQueryStateValue = null
}
setQueryState({ [itemName]: newQueryStateValue }, opts)
},
[defaultValue, itemName, setQueryState]
)
// fallback to default value
let value = defaultValue
const queryStateItem = queryState[itemName]
let queryStateValue = null
if (queryStateItem || queryStateItem === '') {
queryStateValue = parseQueryStateValue(queryStateItem, defaultValue)
}
if (queryStateValue !== null && typeof queryStateValue === typeof defaultValue) {
value = queryStateValue as any
}
return [value, setQueryStateItem]
}
export default function useQueryState(
itemName: string,
defaultValue: T,
queryStateOpts: QueryStateOpts = {}
): [T, SetQueryStateItemFn] {
// defaultValue is not allowed to be changed after init
;[defaultValue] = useState(defaultValue)
const defaultQueryStateValue = toQueryStateValue(defaultValue)
const defaultQueryState = useMemo(() => {
return defaultQueryStateValue
? {
[itemName]: defaultQueryStateValue,
}
: {}
}, [itemName, defaultQueryStateValue])
if (defaultQueryStateValue === null) {
throw new Error('unsupported defaultValue')
}
const [queryState, setQueryState] = useQueryStateObj(defaultQueryState, queryStateOpts)
const setQueryStateItem: SetQueryStateItemFn = useCallback(
(newValue, opts) => {
// stringify the given value (or array of strings)
// we remove them to avoid having two URLs reproducing the same state unless stripDefaults === false
if (stripDefaults) {
Object.entries(newState).forEach(([key]) => {
if (defaultQueryState[key] === newState[key]) {
stripOverwrite[key] = null
}
})
}
// retrieve the last value (by re-executing the search getter)
const currentQueryState: QueryState = {
...defaultQueryState,
...parseQueryState(activeQSI.getQueryString()),
}
const mergedQueryString = createMergedQuery(currentQueryState || {}, newState, stripOverwrite)
activeQSI.setQueryString(mergedQueryString, opts || {})
// triggers an update (in case the QueryStringInterface misses to do so)
setLatestMergedQueryString(mergedQueryString)
}, [])
() => ({
...defaultQueryState,
...parseQueryState(queryString),
}),
[defaultQueryState, queryString]