保留react-router中的查询参数

时间:2016-03-06 16:57:27

标签: reactjs react-router

在我的反应应用程序中,我有一些用户访问应用程序的参数,这些参数提供了有关它们来自何处的一些信息。有没有办法使用react-router在整个应用程序中保留这些查询参数。这意味着每次路由更改时都会像那些查询参数一样留在网址中。我见过的唯一例子是在路由之间传递查询参数但不为每条路径保留它们。

2 个答案:

答案 0 :(得分:2)

我在Typescript中写了这个小OCP v3(它与history v3兼容)增强器。它将保留给定的查询参数集。注意 - 传递给此函数的历史记录必须使用react-router进行增强。

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))
        }
    }
}

现在用它来创建历史记录:

import useQueries from 'history/lib/useQueries'
import createBrowserHistory from 'history/lib/createBrowserHistory'
import preserveQueryHistory from './preserveQueryHistory'

const history = preserveQueryHistory(useQueries(createBrowserHistory)(), ['language'])

在react-router中:

<Router history={history}>
...
</Router>

更多终极解决方案,具有CreateHistory增强功能,可嵌入应用useQueries增强器并提供注入自定义History增强器的功能:

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<H>(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<O, H, H2>(createHistory: CreateHistory<O, H>,
    queryParameters: string[], enhancer: (h: History) => History & H2): CreateHistory<O, H & H2 & HistoryQueries> {
    return function (options?: HistoryOptions & O): History & H & H2 & HistoryQueries {
        let h = enhancer(useQueries(createHistory)(options)) as History & H & H2 & HistoryQueries
        return enhanceHistory<H & H2 & HistoryQueries>(h, queryParameters)
    }
}

export function createPreserveQueryHistory<O, H>(createHistory: CreateHistory<O, H>,
    queryParameters: string[]): CreateHistory<O, H & HistoryQueries> {
    return createPreserveQueryHistoryWithEnhancer<O, H, {}>(createHistory, queryParameters, h => h)
}

export function preserveQueryHistoryWithEnhancer<H, H2>(history: History & H, queryParameters: string[],
    enhancer: (h: History) => History & H2): History & HistoryQueries & H & H2 {
    return createPreserveQueryHistoryWithEnhancer(
        function () {
            return history
        },
        queryParameters, enhancer)()
}

export function preserveQueryHistory<H>(history: History & H, queryParameters: string[]): History & HistoryQueries & H {
    return preserveQueryHistoryWithEnhancer<H, {}>(history, queryParameters, h => h)
}

使用useQueries react-router-redux v4 History增强器:

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)
})()

当我迁移到react-router v4时,我会更新答案。

答案 1 :(得分:-2)

在这种情况下,您可以使用保存URL状态的商店,并且可以使用browserHistory推送自定义历史记录状态。

https://github.com/reactjs/react-router/blob/master/docs/guides/Histories.md#browserhistory

<md-tabs md-swipe-content="true>
  <md-tab label="one">
    <md-content>
      ....
    </md-content>
  </md-tab>
</md-tabs>

Here是如何在组件外导航的链接