UNPKG

state-in-url

Version:

Store state in URL as in object, types and structure are preserved, with TS validation. Same API as React.useState, wthout any hasssle or boilerplate. Next.js@14-16, react-router@6-7, remix@2, and Astro.

2 lines (1 loc) • 1.31 kB
import r from"react";import{useRouter as v}from"next/navigation.js";import{parseSPObj as p}from"../../parseSPObj.mjs";import{useUrlStateBase as y}from"../../useUrlStateBase/useUrlStateBase.mjs";import{routerHistory as m,isSSR as C,filterUnknownParams as f,filterUnknownParamsClient as H,getSearch as S,getParams as M,subscribeToUrl as j}from"../../utils.mjs";function w(s,t){const c=r.useMemo(()=>t?.useHistory===void 0?true:!!t?.useHistory,[]);const a=v();const U=r.useMemo(()=>({push:(...e)=>{if(c){m.push(...e)}else{a.push(...e)}},replace:(...e)=>{if(c){m.replace(...e)}else{a.replace(...e)}}}),[a]);const{state:d,updateState:u,updateUrl:n,reset:i,getState:b,pendingUrlUpdate:h}=y(s,U,({parse:e})=>{return C?p(f(s,t?.searchParams),s):e(H(s,t?.searchParams||S()))},void 0,t?.searchParams!==void 0);const l=r.useCallback(()=>{if(h())return;u(f(s,p(Object.fromEntries(M(S()).entries()),s)))},[]);r.useEffect(()=>{l();return j(l)},[l]);const o=r.useMemo(()=>{const e={...E};if(t?.scroll!==void 0)e.scroll=t.scroll;if(t?.replace!==void 0)e.replace=t.replace;return e},[t?.scroll,t?.replace]);const P=r.useCallback((e,k)=>n(e,{...o,...k}),[n,o]);const g=r.useCallback(e=>{i({...o,...e})},[i,o]);return{setState:u,setUrl:P,urlState:d,reset:g,getState:b}}const E={replace:true,scroll:false};export{w as useUrlState};