fix: simplify searchParams provider, leverage next router properly (#5273)
This commit is contained in:
@@ -1,6 +1,7 @@
|
|||||||
'use client'
|
'use client'
|
||||||
import * as facelessUIImport from '@faceless-ui/modal'
|
import * as facelessUIImport from '@faceless-ui/modal'
|
||||||
import { getTranslation } from '@payloadcms/translations'
|
import { getTranslation } from '@payloadcms/translations'
|
||||||
|
import { useRouter } from 'next/navigation.js'
|
||||||
import React, { useCallback, useState } from 'react'
|
import React, { useCallback, useState } from 'react'
|
||||||
import { toast } from 'react-toastify'
|
import { toast } from 'react-toastify'
|
||||||
|
|
||||||
@@ -33,7 +34,8 @@ export const DeleteMany: React.FC<Props> = (props) => {
|
|||||||
const { count, getQueryParams, selectAll, toggleAll } = useSelection()
|
const { count, getQueryParams, selectAll, toggleAll } = useSelection()
|
||||||
const { i18n, t } = useTranslation()
|
const { i18n, t } = useTranslation()
|
||||||
const [deleting, setDeleting] = useState(false)
|
const [deleting, setDeleting] = useState(false)
|
||||||
const { dispatchSearchParams } = useSearchParams()
|
const router = useRouter()
|
||||||
|
const { stringifyParams } = useSearchParams()
|
||||||
|
|
||||||
const collectionPermissions = permissions?.collections?.[slug]
|
const collectionPermissions = permissions?.collections?.[slug]
|
||||||
const hasDeletePermission = collectionPermissions?.delete?.permission
|
const hasDeletePermission = collectionPermissions?.delete?.permission
|
||||||
@@ -60,11 +62,14 @@ export const DeleteMany: React.FC<Props> = (props) => {
|
|||||||
if (res.status < 400) {
|
if (res.status < 400) {
|
||||||
toast.success(json.message || t('general:deletedSuccessfully'), { autoClose: 3000 })
|
toast.success(json.message || t('general:deletedSuccessfully'), { autoClose: 3000 })
|
||||||
toggleAll()
|
toggleAll()
|
||||||
dispatchSearchParams({
|
router.replace(
|
||||||
type: 'SET',
|
stringifyParams({
|
||||||
browserHistory: 'replace',
|
params: {
|
||||||
params: { page: selectAll ? '1' : undefined },
|
page: selectAll ? '1' : undefined,
|
||||||
})
|
},
|
||||||
|
replace: true,
|
||||||
|
}),
|
||||||
|
)
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -81,13 +86,14 @@ export const DeleteMany: React.FC<Props> = (props) => {
|
|||||||
}, [
|
}, [
|
||||||
addDefaultError,
|
addDefaultError,
|
||||||
api,
|
api,
|
||||||
dispatchSearchParams,
|
|
||||||
getQueryParams,
|
getQueryParams,
|
||||||
i18n.language,
|
i18n.language,
|
||||||
modalSlug,
|
modalSlug,
|
||||||
|
router,
|
||||||
selectAll,
|
selectAll,
|
||||||
serverURL,
|
serverURL,
|
||||||
slug,
|
slug,
|
||||||
|
stringifyParams,
|
||||||
t,
|
t,
|
||||||
toggleAll,
|
toggleAll,
|
||||||
toggleModal,
|
toggleModal,
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ import type { FormState } from 'payload/types'
|
|||||||
|
|
||||||
import * as facelessUIImport from '@faceless-ui/modal'
|
import * as facelessUIImport from '@faceless-ui/modal'
|
||||||
import { getTranslation } from '@payloadcms/translations'
|
import { getTranslation } from '@payloadcms/translations'
|
||||||
|
import { useRouter } from 'next/navigation.js'
|
||||||
import React, { useCallback, useState } from 'react'
|
import React, { useCallback, useState } from 'react'
|
||||||
|
|
||||||
import type { Props } from './types.js'
|
import type { Props } from './types.js'
|
||||||
@@ -102,7 +103,8 @@ export const EditMany: React.FC<Props> = (props) => {
|
|||||||
const { count, getQueryParams, selectAll } = useSelection()
|
const { count, getQueryParams, selectAll } = useSelection()
|
||||||
const { i18n, t } = useTranslation()
|
const { i18n, t } = useTranslation()
|
||||||
const [selected, setSelected] = useState([])
|
const [selected, setSelected] = useState([])
|
||||||
const { dispatchSearchParams } = useSearchParams()
|
const { stringifyParams } = useSearchParams()
|
||||||
|
const router = useRouter()
|
||||||
const { componentMap } = useComponentMap()
|
const { componentMap } = useComponentMap()
|
||||||
const [reducedFieldMap, setReducedFieldMap] = useState([])
|
const [reducedFieldMap, setReducedFieldMap] = useState([])
|
||||||
const [initialState, setInitialState] = useState<FormState>()
|
const [initialState, setInitialState] = useState<FormState>()
|
||||||
@@ -155,11 +157,11 @@ export const EditMany: React.FC<Props> = (props) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const onSuccess = () => {
|
const onSuccess = () => {
|
||||||
dispatchSearchParams({
|
router.replace(
|
||||||
type: 'SET',
|
stringifyParams({
|
||||||
browserHistory: 'replace',
|
params: { page: selectAll === SelectAllStatus.AllAvailable ? '1' : undefined },
|
||||||
params: { page: selectAll === SelectAllStatus.AllAvailable ? '1' : undefined },
|
}),
|
||||||
})
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import { getTranslation } from '@payloadcms/translations'
|
import { getTranslation } from '@payloadcms/translations'
|
||||||
|
import { useRouter } from 'next/navigation.js'
|
||||||
import React from 'react'
|
import React from 'react'
|
||||||
|
|
||||||
import { useConfig } from '../../providers/Config/index.js'
|
import { useConfig } from '../../providers/Config/index.js'
|
||||||
@@ -21,7 +22,8 @@ const Localizer: React.FC<{
|
|||||||
|
|
||||||
const { i18n } = useTranslation()
|
const { i18n } = useTranslation()
|
||||||
const locale = useLocale()
|
const locale = useLocale()
|
||||||
const { dispatchSearchParams, searchParams } = useSearchParams()
|
const { stringifyParams } = useSearchParams()
|
||||||
|
const router = useRouter()
|
||||||
|
|
||||||
if (localization) {
|
if (localization) {
|
||||||
const { locales } = localization
|
const { locales } = localization
|
||||||
@@ -34,25 +36,21 @@ const Localizer: React.FC<{
|
|||||||
render={({ close }) => (
|
render={({ close }) => (
|
||||||
<PopupList.ButtonGroup>
|
<PopupList.ButtonGroup>
|
||||||
{locales.map((localeOption) => {
|
{locales.map((localeOption) => {
|
||||||
const newParams = {
|
|
||||||
...searchParams,
|
|
||||||
locale: localeOption.code,
|
|
||||||
}
|
|
||||||
const localeOptionLabel = getTranslation(localeOption.label, i18n)
|
const localeOptionLabel = getTranslation(localeOption.label, i18n)
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<PopupList.Button
|
<PopupList.Button
|
||||||
active={locale.code === localeOption.code}
|
active={locale.code === localeOption.code}
|
||||||
href={{ query: newParams }}
|
|
||||||
key={localeOption.code}
|
key={localeOption.code}
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
|
router.replace(
|
||||||
|
stringifyParams({
|
||||||
|
params: {
|
||||||
|
locale: localeOption.code,
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
)
|
||||||
close()
|
close()
|
||||||
dispatchSearchParams({
|
|
||||||
type: 'SET',
|
|
||||||
params: {
|
|
||||||
locale: searchParams.locale,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{localeOptionLabel}
|
{localeOptionLabel}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
'use client'
|
'use client'
|
||||||
import * as facelessUIImport from '@faceless-ui/modal'
|
import * as facelessUIImport from '@faceless-ui/modal'
|
||||||
import { getTranslation } from '@payloadcms/translations'
|
import { getTranslation } from '@payloadcms/translations'
|
||||||
|
import { useRouter } from 'next/navigation.js'
|
||||||
import React, { useCallback, useState } from 'react'
|
import React, { useCallback, useState } from 'react'
|
||||||
import { toast } from 'react-toastify'
|
import { toast } from 'react-toastify'
|
||||||
|
|
||||||
@@ -33,7 +34,8 @@ export const PublishMany: React.FC<Props> = (props) => {
|
|||||||
const { i18n, t } = useTranslation()
|
const { i18n, t } = useTranslation()
|
||||||
const { getQueryParams, selectAll } = useSelection()
|
const { getQueryParams, selectAll } = useSelection()
|
||||||
const [submitted, setSubmitted] = useState(false)
|
const [submitted, setSubmitted] = useState(false)
|
||||||
const { dispatchSearchParams } = useSearchParams()
|
const router = useRouter()
|
||||||
|
const { stringifyParams } = useSearchParams()
|
||||||
|
|
||||||
const collectionPermissions = permissions?.collections?.[slug]
|
const collectionPermissions = permissions?.collections?.[slug]
|
||||||
const hasPermission = collectionPermissions?.update?.permission
|
const hasPermission = collectionPermissions?.update?.permission
|
||||||
@@ -65,11 +67,13 @@ export const PublishMany: React.FC<Props> = (props) => {
|
|||||||
toggleModal(modalSlug)
|
toggleModal(modalSlug)
|
||||||
if (res.status < 400) {
|
if (res.status < 400) {
|
||||||
toast.success(t('general:updatedSuccessfully'))
|
toast.success(t('general:updatedSuccessfully'))
|
||||||
dispatchSearchParams({
|
router.replace(
|
||||||
type: 'SET',
|
stringifyParams({
|
||||||
browserHistory: 'replace',
|
params: {
|
||||||
params: { page: selectAll ? '1' : undefined },
|
page: selectAll ? '1' : undefined,
|
||||||
})
|
},
|
||||||
|
}),
|
||||||
|
)
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -94,7 +98,6 @@ export const PublishMany: React.FC<Props> = (props) => {
|
|||||||
slug,
|
slug,
|
||||||
t,
|
t,
|
||||||
toggleModal,
|
toggleModal,
|
||||||
dispatchSearchParams,
|
|
||||||
])
|
])
|
||||||
|
|
||||||
if (!versions?.drafts || selectAll === SelectAllStatus.None || !hasPermission) {
|
if (!versions?.drafts || selectAll === SelectAllStatus.None || !hasPermission) {
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
'use client'
|
'use client'
|
||||||
import * as facelessUIImport from '@faceless-ui/modal'
|
import * as facelessUIImport from '@faceless-ui/modal'
|
||||||
import { getTranslation } from '@payloadcms/translations'
|
import { getTranslation } from '@payloadcms/translations'
|
||||||
|
import { useRouter } from 'next/navigation.js'
|
||||||
import React, { useCallback, useState } from 'react'
|
import React, { useCallback, useState } from 'react'
|
||||||
import { toast } from 'react-toastify'
|
import { toast } from 'react-toastify'
|
||||||
|
|
||||||
@@ -32,7 +33,8 @@ export const UnpublishMany: React.FC<Props> = (props) => {
|
|||||||
const { i18n, t } = useTranslation()
|
const { i18n, t } = useTranslation()
|
||||||
const { getQueryParams, selectAll } = useSelection()
|
const { getQueryParams, selectAll } = useSelection()
|
||||||
const [submitted, setSubmitted] = useState(false)
|
const [submitted, setSubmitted] = useState(false)
|
||||||
const { dispatchSearchParams } = useSearchParams()
|
const { stringifyParams } = useSearchParams()
|
||||||
|
const router = useRouter()
|
||||||
|
|
||||||
const collectionPermissions = permissions?.collections?.[slug]
|
const collectionPermissions = permissions?.collections?.[slug]
|
||||||
const hasPermission = collectionPermissions?.update?.permission
|
const hasPermission = collectionPermissions?.update?.permission
|
||||||
@@ -61,11 +63,13 @@ export const UnpublishMany: React.FC<Props> = (props) => {
|
|||||||
toggleModal(modalSlug)
|
toggleModal(modalSlug)
|
||||||
if (res.status < 400) {
|
if (res.status < 400) {
|
||||||
toast.success(t('general:updatedSuccessfully'))
|
toast.success(t('general:updatedSuccessfully'))
|
||||||
dispatchSearchParams({
|
router.replace(
|
||||||
type: 'SET',
|
stringifyParams({
|
||||||
browserHistory: 'replace',
|
params: {
|
||||||
params: { page: selectAll ? '1' : undefined },
|
page: selectAll ? '1' : undefined,
|
||||||
})
|
},
|
||||||
|
}),
|
||||||
|
)
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -82,7 +86,6 @@ export const UnpublishMany: React.FC<Props> = (props) => {
|
|||||||
}, [
|
}, [
|
||||||
addDefaultError,
|
addDefaultError,
|
||||||
api,
|
api,
|
||||||
dispatchSearchParams,
|
|
||||||
getQueryParams,
|
getQueryParams,
|
||||||
i18n.language,
|
i18n.language,
|
||||||
modalSlug,
|
modalSlug,
|
||||||
|
|||||||
@@ -2,8 +2,6 @@
|
|||||||
|
|
||||||
import type { Locale } from 'payload/config'
|
import type { Locale } from 'payload/config'
|
||||||
|
|
||||||
// TODO: abstract the `next/navigation` dependency out from this component
|
|
||||||
import { useRouter } from 'next/navigation.js'
|
|
||||||
import React, { createContext, useContext, useEffect, useState } from 'react'
|
import React, { createContext, useContext, useEffect, useState } from 'react'
|
||||||
|
|
||||||
import { findLocaleFromCode } from '../../utilities/findLocaleFromCode.js'
|
import { findLocaleFromCode } from '../../utilities/findLocaleFromCode.js'
|
||||||
@@ -18,15 +16,14 @@ export const LocaleProvider: React.FC<{ children?: React.ReactNode }> = ({ child
|
|||||||
const { localization } = useConfig()
|
const { localization } = useConfig()
|
||||||
|
|
||||||
const { user } = useAuth()
|
const { user } = useAuth()
|
||||||
|
|
||||||
const defaultLocale =
|
const defaultLocale =
|
||||||
localization && localization.defaultLocale ? localization.defaultLocale : 'en'
|
localization && localization.defaultLocale ? localization.defaultLocale : 'en'
|
||||||
|
|
||||||
const { dispatchSearchParams, searchParams } = useSearchParams()
|
const { searchParams } = useSearchParams()
|
||||||
const router = useRouter()
|
const localeFromParams = searchParams?.locale || ''
|
||||||
|
|
||||||
const [localeCode, setLocaleCode] = useState<string>(
|
const [localeCode, setLocaleCode] = useState<string>(
|
||||||
(searchParams?.locale as string) || defaultLocale,
|
(localeFromParams as string) || defaultLocale,
|
||||||
)
|
)
|
||||||
|
|
||||||
const [locale, setLocale] = useState<Locale | null>(
|
const [locale, setLocale] = useState<Locale | null>(
|
||||||
@@ -35,53 +32,55 @@ export const LocaleProvider: React.FC<{ children?: React.ReactNode }> = ({ child
|
|||||||
|
|
||||||
const { getPreference, setPreference } = usePreferences()
|
const { getPreference, setPreference } = usePreferences()
|
||||||
|
|
||||||
const localeFromParams = searchParams.locale
|
const switchLocale = React.useCallback(
|
||||||
|
async (newLocale: string) => {
|
||||||
useEffect(() => {
|
|
||||||
async function localeChangeHandler() {
|
|
||||||
if (!localization) {
|
if (!localization) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// set locale from search param
|
const localeToSet =
|
||||||
if (localeFromParams && localization.localeCodes.indexOf(localeFromParams as string) > -1) {
|
localization.localeCodes.indexOf(newLocale) > -1 ? newLocale : defaultLocale
|
||||||
setLocaleCode(localeFromParams as string)
|
|
||||||
setLocale(findLocaleFromCode(localization, localeFromParams as string))
|
|
||||||
if (user) await setPreference('locale', localeFromParams)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// set locale from preferences or default
|
if (localeToSet !== localeCode) {
|
||||||
let preferenceLocale: string
|
setLocaleCode(localeToSet)
|
||||||
let isPreferenceInConfig: boolean
|
setLocale(findLocaleFromCode(localization, localeToSet))
|
||||||
if (user) {
|
try {
|
||||||
preferenceLocale = await getPreference<string>('locale')
|
if (user) await setPreference('locale', localeToSet)
|
||||||
isPreferenceInConfig =
|
} catch (error) {
|
||||||
preferenceLocale && localization.localeCodes.indexOf(preferenceLocale) > -1
|
// swallow error
|
||||||
if (isPreferenceInConfig) {
|
|
||||||
setLocaleCode(preferenceLocale)
|
|
||||||
setLocale(findLocaleFromCode(localization, preferenceLocale))
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
await setPreference('locale', defaultLocale)
|
|
||||||
}
|
}
|
||||||
setLocaleCode(defaultLocale)
|
},
|
||||||
setLocale(findLocaleFromCode(localization, defaultLocale))
|
[localization, setPreference, user, defaultLocale, localeCode],
|
||||||
}
|
)
|
||||||
|
|
||||||
void localeChangeHandler()
|
|
||||||
}, [defaultLocale, getPreference, localeFromParams, setPreference, user, localization, router])
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (searchParams?.locale) {
|
async function setInitialLocale() {
|
||||||
dispatchSearchParams({
|
let localeToSet = defaultLocale
|
||||||
type: 'SET',
|
|
||||||
params: {
|
if (typeof localeFromParams === 'string') {
|
||||||
locale: searchParams.locale,
|
localeToSet = localeFromParams
|
||||||
},
|
} else if (user) {
|
||||||
})
|
try {
|
||||||
|
localeToSet = await getPreference<string>('locale')
|
||||||
|
} catch (error) {
|
||||||
|
// swallow error
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
await switchLocale(localeToSet)
|
||||||
}
|
}
|
||||||
}, [searchParams.locale, dispatchSearchParams])
|
|
||||||
|
void setInitialLocale()
|
||||||
|
}, [
|
||||||
|
defaultLocale,
|
||||||
|
getPreference,
|
||||||
|
localization,
|
||||||
|
localeFromParams,
|
||||||
|
setPreference,
|
||||||
|
user,
|
||||||
|
switchLocale,
|
||||||
|
])
|
||||||
|
|
||||||
return <LocaleContext.Provider value={locale}>{children}</LocaleContext.Provider>
|
return <LocaleContext.Provider value={locale}>{children}</LocaleContext.Provider>
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,13 +1,13 @@
|
|||||||
'use client'
|
'use client'
|
||||||
import { useSearchParams as useNextSearchParams, useRouter } from 'next/navigation.js'
|
import { useSearchParams as useNextSearchParams } from 'next/navigation.js'
|
||||||
import qs from 'qs'
|
import qs from 'qs'
|
||||||
import React, { createContext, useContext } from 'react'
|
import React, { createContext, useContext } from 'react'
|
||||||
|
|
||||||
import type { Action, SearchParamsContext, State } from './types.js'
|
import type { SearchParamsContext, State } from './types.js'
|
||||||
|
|
||||||
const initialContext: SearchParamsContext = {
|
const initialContext: SearchParamsContext = {
|
||||||
dispatchSearchParams: () => {},
|
|
||||||
searchParams: {},
|
searchParams: {},
|
||||||
|
stringifyParams: () => '',
|
||||||
}
|
}
|
||||||
|
|
||||||
const Context = createContext(initialContext)
|
const Context = createContext(initialContext)
|
||||||
@@ -15,46 +15,36 @@ const Context = createContext(initialContext)
|
|||||||
// TODO: abstract the `next/navigation` dependency out from this provider so that it can be used in other contexts
|
// TODO: abstract the `next/navigation` dependency out from this provider so that it can be used in other contexts
|
||||||
export const SearchParamsProvider: React.FC<{ children?: React.ReactNode }> = ({ children }) => {
|
export const SearchParamsProvider: React.FC<{ children?: React.ReactNode }> = ({ children }) => {
|
||||||
const nextSearchParams = useNextSearchParams()
|
const nextSearchParams = useNextSearchParams()
|
||||||
const router = useRouter()
|
const searchString = nextSearchParams.toString()
|
||||||
const initialParams = qs.parse(nextSearchParams.toString(), {
|
const initialParams = qs.parse(searchString, {
|
||||||
depth: 10,
|
depth: 10,
|
||||||
ignoreQueryPrefix: true,
|
ignoreQueryPrefix: true,
|
||||||
})
|
})
|
||||||
|
|
||||||
const [searchParams, dispatchSearchParams] = React.useReducer((state: State, action: Action) => {
|
const [searchParams, setSearchParams] = React.useState(initialParams)
|
||||||
const stackAction = action.browserHistory || 'push'
|
|
||||||
let paramsToSet
|
|
||||||
|
|
||||||
switch (action.type) {
|
const stringifyParams = React.useCallback(
|
||||||
case 'SET':
|
({ params, replace = false }: { params: State; replace?: boolean }) => {
|
||||||
paramsToSet = {
|
return qs.stringify(
|
||||||
...state,
|
{
|
||||||
...action.params,
|
...(replace ? {} : searchParams),
|
||||||
}
|
...params,
|
||||||
break
|
},
|
||||||
case 'REPLACE':
|
{ addQueryPrefix: true },
|
||||||
paramsToSet = action.params
|
)
|
||||||
break
|
},
|
||||||
case 'CLEAR':
|
[searchParams],
|
||||||
paramsToSet = {}
|
|
||||||
break
|
|
||||||
default:
|
|
||||||
return state
|
|
||||||
}
|
|
||||||
|
|
||||||
const newSearchString = qs.stringify(paramsToSet, { addQueryPrefix: true })
|
|
||||||
if (stackAction === 'push') {
|
|
||||||
router.push(newSearchString)
|
|
||||||
} else if (stackAction === 'replace') {
|
|
||||||
router.replace(newSearchString)
|
|
||||||
}
|
|
||||||
|
|
||||||
return paramsToSet
|
|
||||||
}, initialParams)
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Context.Provider value={{ dispatchSearchParams, searchParams }}>{children}</Context.Provider>
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
React.useEffect(() => {
|
||||||
|
const newSearchParams = qs.parse(searchString, {
|
||||||
|
depth: 10,
|
||||||
|
ignoreQueryPrefix: true,
|
||||||
|
})
|
||||||
|
setSearchParams(newSearchParams)
|
||||||
|
}, [searchString])
|
||||||
|
|
||||||
|
return <Context.Provider value={{ searchParams, stringifyParams }}>{children}</Context.Provider>
|
||||||
}
|
}
|
||||||
|
|
||||||
export const useSearchParams = (): SearchParamsContext => useContext(Context)
|
export const useSearchParams = (): SearchParamsContext => useContext(Context)
|
||||||
|
|||||||
@@ -1,27 +1,6 @@
|
|||||||
export type SearchParamsContext = {
|
export type SearchParamsContext = {
|
||||||
dispatchSearchParams: (action: Action) => void
|
|
||||||
searchParams: qs.ParsedQs
|
searchParams: qs.ParsedQs
|
||||||
|
stringifyParams: ({ params, replace }: { params: State; replace?: boolean }) => string
|
||||||
}
|
}
|
||||||
|
|
||||||
export type State = qs.ParsedQs
|
export type State = qs.ParsedQs
|
||||||
|
|
||||||
export type Action = (
|
|
||||||
| {
|
|
||||||
params: qs.ParsedQs
|
|
||||||
type: 'REPLACE'
|
|
||||||
}
|
|
||||||
| {
|
|
||||||
params: qs.ParsedQs
|
|
||||||
type: 'SET'
|
|
||||||
}
|
|
||||||
| {
|
|
||||||
type: 'CLEAR'
|
|
||||||
}
|
|
||||||
) & {
|
|
||||||
/**
|
|
||||||
* `push` will add a new entry to the browser history stack.
|
|
||||||
* `replace` will overwrite the browser history entry.
|
|
||||||
* @default 'push'
|
|
||||||
* */
|
|
||||||
browserHistory?: 'push' | 'replace'
|
|
||||||
}
|
|
||||||
|
|||||||
Reference in New Issue
Block a user