Skip to content

Commit

Permalink
fix(react-router): separate internal and user provided history state (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
ferretwithaberet authored Jan 10, 2025
1 parent 9f028a5 commit 814ebfe
Show file tree
Hide file tree
Showing 6 changed files with 22 additions and 16 deletions.
2 changes: 1 addition & 1 deletion docs/framework/react/api/router/RouterType.md
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ Builds a new parsed location object that can be used later to navigate to a new
- Optional
- If `true`, the current hash will be used. If a function is provided, it will be called with the current hash and the return value will be used.
- `state`
- Type: `true | NonNullableUpdater<HistoryState>`
- Type: `true | NonNullableUpdater<ParsedHistoryState, HistoryState>`
- Optional
- If `true`, the current state will be used. If a function is provided, it will be called with the current state and the return value will be used.
- `mask`
Expand Down
12 changes: 7 additions & 5 deletions packages/history/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ export interface RouterHistory {
}

export interface HistoryLocation extends ParsedPath {
state: HistoryState
state: ParsedHistoryState
}

export interface ParsedPath {
Expand All @@ -50,7 +50,9 @@ export interface ParsedPath {
hash: string
}

export interface HistoryState {
export interface HistoryState {}

export type ParsedHistoryState = HistoryState & {
key?: string
__TSR_index: number
}
Expand Down Expand Up @@ -254,7 +256,7 @@ function assignKeyAndIndex(index: number, state: HistoryState | undefined) {
...state,
key: createRandomKey(),
[stateIndexKey]: index,
}
} as ParsedHistoryState
}

/**
Expand Down Expand Up @@ -553,7 +555,7 @@ export function createMemoryHistory(
let index = opts.initialIndex
? Math.min(Math.max(opts.initialIndex, 0), entries.length - 1)
: entries.length - 1
const states = entries.map<HistoryState>((_entry, index) =>
const states = entries.map((_entry, index) =>
assignKeyAndIndex(index, undefined),
)

Expand Down Expand Up @@ -591,7 +593,7 @@ export function createMemoryHistory(

export function parseHref(
href: string,
state: HistoryState | undefined,
state: ParsedHistoryState | undefined,
): HistoryLocation {
const hashIndex = href.indexOf('#')
const searchIndex = href.indexOf('?')
Expand Down
4 changes: 2 additions & 2 deletions packages/react-router/src/link.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import {
import { exactPathTest, removeTrailingSlash } from './path'
import { useMatch } from './useMatch'
import type { ParsedLocation } from './location'
import type { HistoryState } from '@tanstack/history'
import type { HistoryState, ParsedHistoryState } from '@tanstack/history'
import type {
AllParams,
CatchAllPaths,
Expand Down Expand Up @@ -254,7 +254,7 @@ export type ToSubOptionsProps<
TTo extends string | undefined = '.',
> = MakeToRequired<TRouter, TFrom, TTo> & {
hash?: true | Updater<string>
state?: true | NonNullableUpdater<HistoryState>
state?: true | NonNullableUpdater<ParsedHistoryState, HistoryState>
from?: FromPathOption<TRouter, TFrom> & {}
}

Expand Down
4 changes: 2 additions & 2 deletions packages/react-router/src/location.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import type { HistoryState } from '@tanstack/history'
import type { ParsedHistoryState } from '@tanstack/history'
import type { AnySchema } from './validators'

export interface ParsedLocation<TSearchObj extends AnySchema = {}> {
href: string
pathname: string
search: TSearchObj
searchStr: string
state: HistoryState
state: ParsedHistoryState
hash: string
maskedLocation?: ParsedLocation<TSearchObj>
unmaskOnReload?: boolean
Expand Down
10 changes: 7 additions & 3 deletions packages/react-router/src/router.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ import type * as React from 'react'
import type {
HistoryLocation,
HistoryState,
ParsedHistoryState,
RouterHistory,
} from '@tanstack/history'
import type { NoInfer } from '@tanstack/react-store'
Expand Down Expand Up @@ -533,13 +534,13 @@ export interface BuildNextOptions {
params?: true | Updater<unknown>
search?: true | Updater<unknown>
hash?: true | Updater<string>
state?: true | NonNullableUpdater<HistoryState>
state?: true | NonNullableUpdater<ParsedHistoryState, HistoryState>
mask?: {
to?: string | number | null
params?: true | Updater<unknown>
search?: true | Updater<unknown>
hash?: true | Updater<string>
state?: true | NonNullableUpdater<HistoryState>
state?: true | NonNullableUpdater<ParsedHistoryState, HistoryState>
unmaskOnReload?: boolean
}
from?: string
Expand Down Expand Up @@ -1569,7 +1570,10 @@ export class Router<
let nextParams =
(dest.params ?? true) === true
? prevParams
: { ...prevParams, ...functionalUpdate(dest.params, prevParams) }
: {
...prevParams,
...functionalUpdate(dest.params as any, prevParams),
}

if (Object.keys(nextParams).length > 0) {
matchedRoutesResult?.matchedRoutes
Expand Down
6 changes: 3 additions & 3 deletions packages/react-router/src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -161,9 +161,9 @@ function isFunction(d: any): d is Function {
return typeof d === 'function'
}

export function functionalUpdate<TResult>(
updater: Updater<TResult> | NonNullableUpdater<TResult>,
previous: TResult,
export function functionalUpdate<TPrevious, TResult = TPrevious>(
updater: Updater<TPrevious, TResult> | NonNullableUpdater<TPrevious, TResult>,
previous: TPrevious,
): TResult {
if (isFunction(updater)) {
return updater(previous)
Expand Down

0 comments on commit 814ebfe

Please sign in to comment.