2016-03-06 94 views
6

在我的反應應用程序中,我有幾個用戶來到應用程序的參數,它們提供了一些關於它們來自哪裏的信息。有沒有一種方法使用react-router在整個應用程序中保留這些查詢參數。這意味着每次路線更改時,Id都會將這些查詢參數保留在url中。我見過的唯一例子是在路由之間傳遞查詢參數,但不保留每條路由。在react-router中保留查詢參數

+0

您是否曾經爲此找到過解決方案? – Josh

+2

種。我攔截了history.listen並添加了一個檢查來查看參數是否存在。如果他們不是我從redux中加入他們。它現在可以正常工作,但我想直接在react-router中創建一些內容。 – ThrowsException

+0

是否適用於反應路由器v4? –

回答

1

我在打字稿寫了這個小history V3(它與react-router V3兼容)增強。它將保留給定的一組查詢參數。要小心 - 傳遞給此函數的歷史記錄必須使用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)) 
     } 
    } 
} 

現在用它來創造歷史:

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

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

而在反應路由器:

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

更多終極解決方案與嵌入應用useQueries增強,並提供CreateHistory增強功能注入自定義能力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) 
} 

用法與syncHistoryWithStore反應路由器,終極版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) 
})() 

我會更新的答案的時候,我會遷移到反應路由器V4。

+0

很酷的解決方案。絕對比我想冒險寫我自己的歷史模塊更進一步。 – ThrowsException