Javascript 如何在react router v4中保留查询参数
用户在登录后重定向到我的应用程序(java上的服务器),他们有url,如下所示Javascript 如何在react router v4中保留查询参数,javascript,reactjs,react-router,react-router-v4,Javascript,Reactjs,React Router,React Router V4,用户在登录后重定向到我的应用程序(java上的服务器),他们有url,如下所示 (带有一些参数,html是源所在的文件夹)。在我的应用程序上导航时,我需要保留此参数。到目前为止,除了这个老问题,我还没有找到任何简单的解决办法,所以我再次提出这个问题,希望如此。提前感谢。我在这个项目中关闭了哈希路由器,它保留了路由中的所有参数。在React router 4.3(不确定早期版本)中,如果上面有一个,类似的东西应该可以工作:(这是在Typescript中) 说明:您使用标记的渲染:(props)=
(带有一些参数,html是源所在的文件夹)。在我的应用程序上导航时,我需要保留此参数。到目前为止,除了这个老问题,我还没有找到任何简单的解决办法,所以我再次提出这个问题,希望如此。提前感谢。我在这个项目中关闭了哈希路由器,它保留了路由中的所有参数。在React router 4.3(不确定早期版本)中,如果上面有一个
,类似的东西应该可以工作:(这是在Typescript中)
说明:您使用
标记的渲染:(props)=>..
属性,而不是组件:…
,因为渲染
提供道具
,所以在
内可以使用props.location.search
并以这种方式访问当前的查询参数,并在重定向中重用
如果上面没有
,可能您不能。我刚才在这里问:我已经在对你的问题的评论中分享了react router v3
下面是我针对react路由器v4的解决方案
使用以下createPreserveQueryHistory
函数覆盖历史记录。按下和历史记录。替换方法,以便它们保留指定的查询参数:
import queryString from 'query-string';
import {createBrowserHistory} from 'history'
function preserveQueryParameters(history, preserve, location) {
const currentQuery = queryString.parse(history.location.search);
if (currentQuery) {
const preservedQuery = {};
for (let p of preserve) {
const v = currentQuery[p];
if (v) {
preservedQuery[p] = v;
}
}
if (location.search) {
Object.assign(preservedQuery, queryString.parse(location.search));
}
location.search = queryString.stringify(preservedQuery);
}
return location;
}
function createLocationDescriptorObject(location, state) {
return typeof location === 'string' ? { pathname: location, state } : location;
}
function createPreserveQueryHistory(createHistory, queryParameters) {
return (options) => {
const history = createHistory(options);
const oldPush = history.push, oldReplace = history.replace;
history.push = (path, state) => oldPush.apply(history, [preserveQueryParameters(history, queryParameters, createLocationDescriptorObject(path, state))]);
history.replace = (path, state) => oldReplace.apply(history, [preserveQueryParameters(history, queryParameters, createLocationDescriptorObject(path, state))]);
return history;
};
}
const history = createPreserveQueryHistory(createBrowserHistory, ['locale', 'token', 'returnTo'])();
然后在路由器定义中使用它:
<Router history={history}>
...
</Router>
...
对于使用TypeScript的用户:
import {History, LocationDescriptor, LocationDescriptorObject} from 'history'
import queryString from 'query-string'
import LocationState = History.LocationState
type CreateHistory<O, H> = (options?: O) => History & H
function preserveQueryParameters(history: History, preserve: string[], location: LocationDescriptorObject): LocationDescriptorObject {
const currentQuery = queryString.parse(history.location.search)
if (currentQuery) {
const preservedQuery: { [key: string]: unknown } = {}
for (let p of preserve) {
const v = currentQuery[p]
if (v) {
preservedQuery[p] = v
}
}
if (location.search) {
Object.assign(preservedQuery, queryString.parse(location.search))
}
location.search = queryString.stringify(preservedQuery)
}
return location
}
function createLocationDescriptorObject(location: LocationDescriptor, state?: LocationState): LocationDescriptorObject {
return typeof location === 'string' ? {pathname: location, state} : location
}
export function createPreserveQueryHistory<O, H>(createHistory: CreateHistory<O, H>,
queryParameters: string[]): CreateHistory<O, H> {
return (options?: O) => {
const history = createHistory(options)
const oldPush = history.push, oldReplace = history.replace
history.push = (path: LocationDescriptor, state?: LocationState) =>
oldPush.apply(history, [preserveQueryParameters(history, queryParameters, createLocationDescriptorObject(path, state))])
history.replace = (path: LocationDescriptor, state?: LocationState) =>
oldReplace.apply(history, [preserveQueryParameters(history, queryParameters, createLocationDescriptorObject(path, state))])
return history
}
}
从“历史”导入{History,LocationDescriptor,LocationDescriptorObject}
从“查询字符串”导入查询字符串
导入LocationState=History.LocationState
键入CreateHistory=(选项?:O)=>History&H
函数preserveQueryParameters(历史:历史,preserve:string[],位置:LocationDescriptorObject):LocationDescriptorObject{
const currentQuery=queryString.parse(history.location.search)
如果(当前查询){
const preservedQuery:{[key:string]:未知}={}
for(让p保留){
常数v=currentQuery[p]
如果(v){
preservedQuery[p]=v
}
}
if(location.search){
assign(preservedQuery、queryString.parse(location.search))
}
location.search=queryString.stringify(保留查询)
}
返回位置
}
函数createLocationDescriptorObject(位置:位置描述符,状态?:位置状态):位置描述符对象{
返回typeof location=='string'?{pathname:location,state}:location
}
导出函数createPreserveQueryHistory(createHistory:createHistory,
queryParameters:string[]):CreateHistory{
返回(选项?:O)=>{
const history=createHistory(选项)
const oldPush=history.push,oldplace=history.replace
history.push=(路径:LocationDescriptor,状态?:LocationState)=>
apply(历史,[preserveQueryParameters(历史,queryParameters,createLocationDescriptorObject(路径,状态))]))
history.replace=(路径:LocationDescriptor,状态?:LocationState)=>
应用(历史,[preserveQueryParameters(历史,queryParameters,createLocationDescriptorObject(路径,状态))]))
回归历史
}
}
您必须提取这些参数,然后自己将其放入存储区(redux或flex)。我知道如何提取(window.location.search),我可以将其保存在存储区,但如何在所有路线中导航时将其放回?只是正常的调度/减速器循环。还有什么?请澄清。请参阅我的答案createLocationDescriptorObject
对我不起作用。我需要将{pathname:location,state}
部分替换为{…parsePath(location),state}
,其中parsePath
是从历史导入的。@GennadyDogaev,请回复上面的评论,什么不起作用?我使用了{pathname:location,state}
它似乎可以工作,但测试有限。我可能错过了什么?缺少搜索和哈希?@innek这是很久以前的事了,所以我记不起它不起作用的确切原因。这种重定向方法似乎不适用于以下场景。比如说,用户登陆mysite.com/home?devmode=true,站点导航栏上有一个菜单项,该菜单项有指向“mysite.com/projects”的链接。当我点击“mysite.com/projects”时,我想预先设置查询参数devmode=true
。像这样的重定向会导致无限循环``@innek是您认为可能发生的事情还是实际发生的事情?我认为to:…
仅用于路径?(不完全记得。)如果您已经在mysite.com/projects?devmode=true
上,动态构建路由({…重定向({…
列表)并排除重定向,该怎么办?
import {History, LocationDescriptor, LocationDescriptorObject} from 'history'
import queryString from 'query-string'
import LocationState = History.LocationState
type CreateHistory<O, H> = (options?: O) => History & H
function preserveQueryParameters(history: History, preserve: string[], location: LocationDescriptorObject): LocationDescriptorObject {
const currentQuery = queryString.parse(history.location.search)
if (currentQuery) {
const preservedQuery: { [key: string]: unknown } = {}
for (let p of preserve) {
const v = currentQuery[p]
if (v) {
preservedQuery[p] = v
}
}
if (location.search) {
Object.assign(preservedQuery, queryString.parse(location.search))
}
location.search = queryString.stringify(preservedQuery)
}
return location
}
function createLocationDescriptorObject(location: LocationDescriptor, state?: LocationState): LocationDescriptorObject {
return typeof location === 'string' ? {pathname: location, state} : location
}
export function createPreserveQueryHistory<O, H>(createHistory: CreateHistory<O, H>,
queryParameters: string[]): CreateHistory<O, H> {
return (options?: O) => {
const history = createHistory(options)
const oldPush = history.push, oldReplace = history.replace
history.push = (path: LocationDescriptor, state?: LocationState) =>
oldPush.apply(history, [preserveQueryParameters(history, queryParameters, createLocationDescriptorObject(path, state))])
history.replace = (path: LocationDescriptor, state?: LocationState) =>
oldReplace.apply(history, [preserveQueryParameters(history, queryParameters, createLocationDescriptorObject(path, state))])
return history
}
}