如何在 react-router v4 中获取查询参数

Posted

技术标签:

【中文标题】如何在 react-router v4 中获取查询参数【英文标题】:How to get query parameters in react-router v4 【发布时间】:2017-08-30 04:55:10 【问题描述】:

我在我的项目中使用 react-router-dom 4.0.0-beta.6。 我有如下代码:

<Route exact path="/home" component=HomePage/>

我想在HomePage 组件中获取查询参数。 我找到了location.search 参数,看起来像这样:?key=value,所以它是未解析的。

使用 react-router v4 获取查询参数的正确方法是什么?

【问题讨论】:

【参考方案1】:

解析查询字符串的功能已从 V4 中移除,因为多年来一直存在支持不同实现的请求。有了这个,团队决定最好让用户来决定实现的样子。我们建议导入查询字符串库。 Here's one that I use

const queryString = require('query-string');

const parsed = queryString.parse(props.location.search);

如果你想要一些原生的东西,你也可以使用new URLSearchParams,它可以满足你的需要

const params = new URLSearchParams(props.location.search);
const foo = params.get('foo'); // bar

您可以阅读有关决定here的更多信息

【讨论】:

不要使用没有 polyfill 的 URLSearchParams。截至 2018 年 3 月,Googlebot 使用不支持 URLSearchParams 的 Chrome 41 (developers.google.com/search/docs/guides/rendering),如果在关键路径 (caniuse.com/#feat=urlsearchparams) 中使用,您的应用将会中断。 上面的评论(从 2018 年春季开始)提到了 Googlebot 和 URLSearchParams 的不兼容。然而,一年后(2019 年春季)情况有所改善。从那时起,Googlebot 使用最新的 Chromium,因此不再是避免使用 URLSearchParams 的理由。 developers.google.com/search/blog/2019/05/…【参考方案2】:

接受的答案效果很好,但如果你不想安装额外的包,你可以使用这个:

getUrlParameter = (name) => 
    name = name.replace(/[\[]/, '\\[').replace(/[\]]/, '\\]');
    let regex = new RegExp('[\\?&]' + name + '=([^&#]*)');
    let results = regex.exec(window.location.search);
    return results === null ? '' : decodeURIComponent(results[1].replace(/\+/g, ' '));
  ;

给定http://www.google.co.in/?key=value

getUrlParameter('key');

将返回value

【讨论】:

非常感谢。“查询字符串”库由于某种原因对我不起作用,但您的解决方案就像一个魅力。我正在使用“react-dom”:“^16.0.0”,“react-router”:“^4.2.0”,“react-router-dom”:“^4.2.2”和“query-string”: "^5.0.1", 这仅假设您的查询字符串中有一个参数。 OP 清楚地询问如何获取查询参数 - 这就是提到的 npm 模块所做的。把它变成一个函数,从查询字符串中返回一个键/值对对象,这将是真的有用的! @AndyLorenz 当您有多个查询参数时,这甚至可以工作,使用您想要获取其值的键调用给定函数。是的方法也可以转换为键值映射。 这可行,但不是一个好的解决方案@Kartik_Agarwal。 (a) 它需要多次执行基本相同(可能很昂贵)的代码,(b) 需要为每个参数使用单独的变量,而理想情况下,您将填充键/值对的对象,(c) 它需要你知道你的参数名称,并额外检查它们是否存在。如果这是我的代码,我会寻找一个可以迭代地获取所有参数的正则表达式,但我不得不承认正则表达式让我的耳朵流血!【参考方案3】:

我正在研究反应路由器 v4 的参数,他们没有将它用于 v4,不像反应路由器 v2/3。我会留下另一个功能 - 也许有人会发现它有帮助。你只需要 es6 或纯 javascript

function parseQueryParams(query) 
  //You get a '?key=asdfghjkl1234567890&val=123&val2&val3=other'
  const queryArray = query.split('?')[1].split('&');
  let queryParams = ;
  for (let i = 0; i < queryArray.length; i++) 
    const [key, val] = queryArray[i].split('=');
    queryParams[key] = val ? val : true;
  
  /* queryParams = 
     
      key:"asdfghjkl1234567890",
      val:"123",
      val2:true,
      val3:"other"
     
  */
  return queryParams;

另外,这个功能还可以改进

【讨论】:

【参考方案4】:

我刚刚做了这个,所以如果你更新到从较低版本响应路由器 v4 或更高版本,则不需要更改整个代码结构(在其中使用来自 redux 路由器存储的查询)。

https://github.com/saltas888/react-router-query-middleware

【讨论】:

欢迎提供解决方案链接,但请确保您的答案在没有它的情况下有用:add context around the link 这样您的其他用户就会知道它是什么以及为什么会出现,然后引用最相关的您链接到的页面的一部分,以防目标页面不可用。 Answers that are little more than a link may be deleted.【参考方案5】:

给出的答案是可靠的。

如果您想使用qs 模块而不是query-string(它们的受欢迎程度大致相同),语法如下:

const query = qs.parse(props.location.search, 
  ignoreQueryPrefix: true
)

ignoreQueryPrefix 选项是忽略前导问号。

【讨论】:

不错。 2019 年 1 月,qs 的每周下载量为 1200 万次,而查询字符串为 270 万次。【参考方案6】:

不需要任何包:

const params = JSON.parse(JSON.stringify(this.props.match.params));

然后就可以用params.id获取相关参数了

【讨论】:

this.props.match.params 包含路径参数,这个问题是关于查询参数的。【参考方案7】:

嗯?

queryfie(string)
    return string
        .slice(1)
        .split('&')
        .map(q => q.split('='))
        .reduce((a, c) =>  a[c[0]] = c[1]; return a; , );


queryfie(this.props.location.search);

【讨论】:

【参考方案8】:

另一种有用的方法是像这样使用开箱即用的URLSearchParams

  let  search  = useLocation();

   const query = new URLSearchParams(search);
   const paramField = query.get('field');
   const paramValue = query.get('value');

干净、可读且不需要模块。更多信息如下;

https://reacttraining.com/react-router/web/example/query-parameters https://developer.mozilla.org/en-US/docs/Web/API/URLSearchParams

【讨论】:

URLSearchParams 是一个浏览器功能。如果您的客户端使用的浏览器没有它怎么办?【参考方案9】:

很简单

只需使用钩子useParams()

示例:

路由器

<Route path="/user/:id" component=UserComponent />

在您的组件中t:

export default function UserComponent() 

  const  id  = useParams();

  return (
    <>id</>
  );

【讨论】:

这不适用于问题中描述的用例(至少不适用于 React-Router v4:reactrouter.com/web/api/Hooks/useparams)useParams 只公开路径参数,而不是搜索参数。【参考方案10】:

这是一种无需导入任何额外库的方法

const queryString = (string) => 
  return string.slice(1).split('&')
    .map((queryParam) => 
      let data = queryParam.split('=')
      return  key: data[0], value: data[1] 
    )
    .reduce((query, data) => 
      query[data.key] = data.value
      return query
    , );


const paramData = (history && history.location && history.location.search)
                ? parseQueryString(history.location.search)
                : null;

【讨论】:

【参考方案11】:

根据他们的文档https://reactrouter.com/web/example/query-parameters 你需要:

import  useLocation  from 'react-router-dom';

// A custom hook that builds on useLocation to parse
// the query string for you.
function useQuery() 
  return new URLSearchParams(useLocation().search);


function App() 
    const query = useQuery();
    console.log(query.get('queryYouAreLookingFor'));

【讨论】:

【参考方案12】:

React 路由器 v6

来源:Getting Query Strings (Search Params) in React Router

我知道这是 v4 的问题,但是随着 v6 的发布,我们可以在新版本的 React Router 中搜索参数。

使用新的useSearchParams 钩子和.get() 方法:

const Users = () => 
  const [searchParams] = useSearchParams();
  console.log(searchParams.get('sort')); // 'name'

  return <div>Users</div>;
;

使用这种方法,您可以读取一个或几个参数。

阅读更多内容和现场演示:Getting Query Strings (Search Params) in React Router

【讨论】:

以上是关于如何在 react-router v4 中获取查询参数的主要内容,如果未能解决你的问题,请参考以下文章

无法使用 react-router v4 获取“/About”(生产帮助)

如何在 react-router v4 中设置活动链接的样式?

如何使用 react-router v4 检测路由变化?

如何在 react-router v4 的根路由上设置可选参数?

React-router v4教程

使用 Jest 测试来自 react-router v4 的链接