In my react application I have a few parameters that the user comes to the application that provide some information about where they came from. Is there a way using react-r
UPDATE
Solution for react-router v4 is available.
Solution for react-router v3:
I wrote this little history v3 (it's compatible with react-router v3) enhancer in Typescript. It will preserve given set of query parameters. Be careful - history passed to this function has to be enhanced with useQueries.
import {History, Location, LocationDescriptor} from 'history'
export default function preserveQueryHistory(history: History, queryParameters: string[]): History {
function preserveQueryParameters(path: LocationDescriptor): Location {
const location = history.createLocation(path)
const currentQuery = history.getCurrentLocation().query
for (let p of queryParameters) {
const v = (currentQuery as any)[p]
if (v) {
location.query[p] = v
}
}
return location
}
return {
...history,
push(path: LocationDescriptor) {
history.push(preserveQueryParameters(path))
},
replace(path: LocationDescriptor) {
history.replace(preserveQueryParameters(path))
}
}
}
Now use it to create history:
import useQueries from 'history/lib/useQueries'
import createBrowserHistory from 'history/lib/createBrowserHistory'
import preserveQueryHistory from './preserveQueryHistory'
const history = preserveQueryHistory(useQueries(createBrowserHistory)(), ['language'])
And in react-router:
...
More ultimate solution with CreateHistory
enhancer function that embeds applying useQueries
enhancer and provides ability to inject custom History
enhancer:
import {CreateHistory, History, HistoryOptions, HistoryQueries, Location, LocationDescriptor} from 'history'
import useQueries from 'history/lib/useQueries'
function preserveQueryParameters(history: History, queryParameters: string[], path: LocationDescriptor): Location {
const location = history.createLocation(path)
const currentQuery = history.getCurrentLocation().query
for (let p of queryParameters) {
const v = (currentQuery as any)[p]
if (v) {
location.query[p] = v
}
}
return location
}
function enhanceHistory(history: History & H, queryParameters: string[]): History & H {
return Object.assign({}, history, {
push(path: LocationDescriptor) {
history.push(preserveQueryParameters(history, queryParameters, path))
},
replace(path: LocationDescriptor) {
history.replace(preserveQueryParameters(history, queryParameters, path))
}
})
}
export function createPreserveQueryHistoryWithEnhancer(createHistory: CreateHistory,
queryParameters: string[], enhancer: (h: History) => History & H2): CreateHistory {
return function (options?: HistoryOptions & O): History & H & H2 & HistoryQueries {
let h = enhancer(useQueries(createHistory)(options)) as History & H & H2 & HistoryQueries
return enhanceHistory(h, queryParameters)
}
}
export function createPreserveQueryHistory(createHistory: CreateHistory,
queryParameters: string[]): CreateHistory {
return createPreserveQueryHistoryWithEnhancer(createHistory, queryParameters, h => h)
}
export function preserveQueryHistoryWithEnhancer(history: History & H, queryParameters: string[],
enhancer: (h: History) => History & H2): History & HistoryQueries & H & H2 {
return createPreserveQueryHistoryWithEnhancer(
function () {
return history
},
queryParameters, enhancer)()
}
export function preserveQueryHistory(history: History & H, queryParameters: string[]): History & HistoryQueries & H {
return preserveQueryHistoryWithEnhancer(history, queryParameters, h => h)
}
Usage with syncHistoryWithStore react-router-redux v4 History
enhancer:
import createBrowserHistory from 'history/lib/createBrowserHistory'
import {createPreserveQueryHistoryWithEnhancer} from './preserveQueryHistory'
import {syncHistoryWithStore} from 'react-router-redux'
const store = ...
const history = createPreserveQueryHistoryWithEnhancer(createBrowserHistory, ['language'], function (h: History) {
return syncHistoryWithStore(h, store)
})()