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-15 and react-router@6-7.

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