pbeshai / use-query-params

React Hook for managing state in URL query parameters with easy serialization.
https://pbeshai.github.io/use-query-params
ISC License
2.13k stars 95 forks source link

Uncorrect previous params if using callback inside `setQuery` in case of using urlName #249

Open Resetand opened 1 year ago

Resetand commented 1 year ago

Hi, thanks for those amazing libraries. One of the last release contains many really useful updates. urlName was a lifesaver for me because it allowed me to get rid of a lot of workarounds.

And it's seems like i found a bug

Problem

The problem occurs when using urlName

In this example prev object inside setQuery callback will never contain paramWithAlias property, however the query state object will be up to date

const StringParamWithAlias = {...StringParam, urlName: 'alias'}

// URL https:[...]?alias=example&other=here
const [query, setQuery] = useQueryParams({ paramWithAlias: StringParamWithAlias, other: StringParam })

useEffect(() => {
    setQuery(prev => {
        console.log(prev) // ! will be { other: 'here' } without `paramWithAlias`
        return ...
    })
},[])
Resetand commented 1 year ago

This is my current workaround in case anyone needs it

const useQueryParamsWrapper = (paramsConfigMap, options) => {
    const [params, setParams] = useQueryParams(paramsConfigMap, options);

    const paramsRef = useRef(params);
    paramsRef.current = params;

    const setParamsWrapped = useCallback(
        (action, updateType) => {
            const newParams = action instanceof Function ? action(paramsRef.current) : action;
            setParams(newParams);
        },
        [setParams],
    );

    return [params, setParamsWrapped];
};
gregkepler commented 1 year ago

@Resetand Thanks for this workaround. One question - where does "is.Function()" come from? I haven't encountered that yet myself.

Resetand commented 1 year ago

@Resetand Thanks for this workaround. One question - where does "is.Function()" come from? I haven't encountered that yet myself.

It's an internal util. You can use action instanceof Function instead 🙃 PS Updated workaround comment