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, react-router@6-7, and remix@2.

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