@guanriyue/decurl

The default @guanriyue/decurl entry provides ready-to-use React Router hooks. They read the current React Router location and navigate inside the hook, so you do not need to place a Provider manually.

import { useSearchValue, useSearchValues } from '@guanriyue/decurl';

The default hooks use the default singleton search store. For applications with one React Router runtime, this is usually enough.

These hooks must run inside a React Router context, such as BrowserRouter, RouterProvider, or another React Router runtime.

If you need to explicitly provide a store, configure store behavior, or reduce direct dependency on React Router useLocation, see @guanriyue/decurl/provided.

useSearchValues

useSearchValues(searchFields) reads and updates multiple search values.

useSearchValues(searchFields): [values, setValues]

Parameters:

ParameterDescription
searchFieldsA set of Search Fields, usually returned by defineFields.

Returns:

Return valueDescription
valuesValues object decoded from the current URL search params.
setValuesSetter for updating multiple fields.
import { useSearchValues } from '@guanriyue/decurl';

const SearchPanel = () => {
  const [values, setValues] = useSearchValues(searchFields);

  return (
    <button
      type="button"
      onClick={() => {
        setValues({ page: values.page + 1 });
      }}
    >
      Next page
    </button>
  );
};

setValues(patch, options?) accepts a patch. It only updates fields included in the patch, and leaves other fields unchanged. By default, it writes back to the URL with { replace: true }.

Passing null or undefined deletes the corresponding URL key. If the written value equals the field defaultValue, the key is also deleted by default; whether to preserve default values is controlled by the URLSearchParams codec encode rules.

If the whole patch is undefined, Decurl deletes every URL key represented by the current searchFields and preserves search params outside those fields:

setValues(undefined);

The patch can also be an updater:

setValues((previousValues) => ({
  page: previousValues.page + 1,
}));

If the updater returns undefined, it has the same semantics as setValues(undefined).

useSearchValue

useSearchValue(codec) reads and updates a single field. The codec must already have a fixed name, usually from the return value of defineFields.

useSearchValue(codec): [value, setValue]

Parameters:

ParameterDescription
codecA field codec with a fixed name, usually from the return value of defineFields.

Returns:

Return valueDescription
valueSingle field value decoded from the current URL search params.
setValueSetter for updating the single field.
import { useSearchValue } from '@guanriyue/decurl';

const PageButton = () => {
  const [page, setPage] = useSearchValue(searchFields.page);

  return (
    <button
      type="button"
      onClick={() => {
        setPage(page + 1);
      }}
    >
      Next page
    </button>
  );
};

setValue(patch, options?) also supports a direct value or an updater. By default, it writes back to the URL with { replace: true }.

Passing null or undefined deletes the URL key represented by the field. If the written value equals the field defaultValue, the key is also deleted by default.

setPage((previousPage) => previousPage + 1);

Render Behavior

The default hooks read React Router location inside the hook. Some route updates may cause components to re-render with React Router. If you need to centralize React Router capability access in a separate component or observe the related render boundary, see @guanriyue/decurl/provided and Provided Runtime.

The second setter argument is passed through to React Router navigate. Decurl uses replace: true by default to avoid writing frequent search params updates into many history entries.

OptionTypeDefaultDescription
replacebooleantrueWhether to replace the current history entry.
preventScrollResetbooleanReact Router defaultWhether to prevent scroll position reset. It is the same concept as preventScrollReset in React Router navigate options.
setPage(1, { replace: true, preventScrollReset: true });

If multiple setter calls happen before the same flush, the navigate options from the last call override the defaults.

SearchProvider

SearchProvider provides an independent search store and can configure store options. Default hooks first read the nearest SearchProvider store; without a Provider, they use the default global store.

import { SearchProvider } from '@guanriyue/decurl';

<SearchProvider flushDelay={80} flushMode="debounce">
  <App />
</SearchProvider>
PropTypeDescription
flushDelaynumberDelay in milliseconds before search updates are written to the URL.
flushMode'throttle' | 'debounce'Flush scheduling mode.

SearchProvider only provides the store. It does not read React Router location or navigate. Default hooks read React Router capabilities by themselves; provided hooks need to be used with SearchRuntimeConnector.

Types

TypeDescription
SetSearchValues<TFields>Setter type for useSearchValues.
SearchValuesPatch<TFields>Patch type accepted by the useSearchValues setter.
SetSearchValue<TCodec>Setter type for useSearchValue.
SearchValuePatch<TCodec>Patch type accepted by the useSearchValue setter.
UseSearchValuesResult<TFields>Tuple return type of useSearchValues.
UseSearchValueResult<TCodec>Tuple return type of useSearchValue.