从React Router哈希片段获取查询参数

133

我在客户端应用程序中使用React和React-Router。我似乎无法弄清楚如何从类似以下网址的URL中获取以下查询参数:

http://xmen.database/search#/?status=APPROVED&page=1&limit=20

我的路由看起来像这样(我知道路径完全错了):

var routes = (
<Route>
    <DefaultRoute handler={SearchDisplay}/>
    <Route name="search" path="?status=:status&page=:page&limit=:limit" handler={SearchDisplay}/>
    <Route name="xmen" path="candidate/:accountId" handler={XmenDisplay}/>
</Route>
);

我的路由功能正常工作,但我不确定如何格式化路径以获取所需的参数。感谢任何关于此的帮助!


我四处搜索,只能找到一些示例,这些示例是通过“getCurrentQuery”在组件内提取查询字符串参数的。 - Cory Danielson
https://github.com/rackt/react-router/issues/209 - Cory Danielson
你可以在处理程序上使用 willTransitionTo 钩子。它接收查询字符串参数。https://github.com/rackt/react-router/commit/2a75f3ee9ea3f6eccd1c18e84747747bb72ebf38 - Cory Danielson
还有关于转换钩子的文档在这里:https://github.com/rackt/react-router/blob/master/docs/api/components/RouteHandler.md。一旦你解决了这个问题,你应该用你的解决方案来回答这个问题。我相信你不会是遇到这种情况的最后一个人。 - Cory Danielson
10个回答

161

注意:此评论已经复制粘贴。请确保点赞原始帖子!

我在使用 es6 和 react 0.14.6 / react-router 2.0.0-rc5 写作。我使用以下命令在我的组件中查找查询参数:

this.props.location.query

它会创建一个包含URL中所有可用查询参数的哈希值。

更新:

对于React-Router v4,请参见此答案。基本上,使用this.props.location.search获取查询字符串,然后使用query-string包或URLSearchParams进行解析:

const params = new URLSearchParams(paramsString); 
const tags = params.get('tags');

2
这已经不是React-router 1.x或2.x的方式了。 - Peter Aron Zentai
7
根据 Peter 的说法,这个例子已经过时了:请参见 https://dev59.com/310a5IYBdhLWcg3w3L8-#35005474。 - btown
2
在React Router 4中,“query”似乎已经消失了。https://github.com/ReactTraining/react-router/issues/3899#issuecomment-274678710 - mc9

62

上述答案在 react-router v4 中不适用。以下是我解决问题的方法 -

第一步 安装query-string,这是解析所需的。

npm install -save query-string

现在 在路由组件中,您可以像这样访问未解析的查询字符串

this.props.location.search

您可以通过在控制台中记录进行交叉检查。

最后 解析以访问查询参数

const queryString = require('query-string');
var parsed = queryString.parse(this.props.location.search);
console.log(parsed.param); // replace param with your own 

如果查询参数是?hello=world

console.log(parsed.hello)将记录world


20
没有使用库的话: const query = new URLSearchParams(props.location.search); console.log(query.get('hello')); (老旧浏览器需要使用polyfill)。 - Ninh Pham
我构建应用程序时这样做应该可以工作,对吧? - user7075574

59

旧版(v4之前):

使用es6编写,使用react 0.14.6 / react-router 2.0.0-rc5。我在组件中使用以下命令查找查询参数:

this.props.location.query

它会创建一个包含URL中所有可用查询参数的哈希值。
更新(React Router v4+):
在React Router 4中,this.props.location.query已被移除(当前使用v4.1.1),有关此问题的更多信息,请参见:https://github.com/ReactTraining/react-router/issues/4410 看起来他们希望你使用自己的方法来解析查询参数,目前使用这个库来填补空缺:https://github.com/sindresorhus/query-string

2
您IP地址为143.198.54.68,由于运营成本限制,当前对于免费用户的使用频率限制为每个IP每72小时10次对话,如需解除限制,请点击左下角设置图标按钮(手机用户先点击左上角菜单按钮)。 - Thomas Modeneis
3
嘿 @ThomasModeneis,这是你的路由器呈现的最顶层父组件吗?还是一个子组件?如果我没记错的话,你需要从路由器渲染的父组件将this.props.location.query传递到你的子组件中,这是我能想到的唯一解决方法。 - Marrs

17

更新于2017年12月25日

"react-router-dom": "^4.2.2"

URL格式如下:

BrowserHistory: http://localhost:3000/demo-7/detail/2?sort=name

HashHistory: http://localhost:3000/demo-7/#/detail/2?sort=name

使用query-string依赖的情况:

this.id = props.match.params.id;
this.searchObj = queryString.parse(props.location.search);
this.from = props.location.state.from;

console.log(this.id, this.searchObj, this.from);

结果:

2 {sort: "name"} home


"react-router": "^2.4.1"

像这样的网址:http://localhost:8080/react-router01/1?name=novaline&age=26

const queryParams = this.props.location.query;

queryParams是一个包含查询参数的对象:{name: novaline, age: 26}


如果你有类似这样的东西:http://localhost:8090/#access_token=PGqsashgJdrZoU6hV8mWAzwlXkJZO8ImDcn&expires_in=7200&token_type=bearer(即在 # 后面没有 /),那么对于 React Router v4,你应该使用 location.hash 而不是 location.search - codeVerine

15
"react-router-dom": "^5.0.0",

你不需要添加任何额外的模块,只需在具有像这样的URL地址的组件中:

http://localhost:3000/#/?authority'

您可以尝试以下简单代码:

    const search =this.props.location.search;
    const params = new URLSearchParams(search);
    const authority = params.get('authority'); //

10

使用stringquery Package:

import qs from "stringquery";

const obj = qs("?status=APPROVED&page=1limit=20");  
// > { limit: "10", page:"1", status:"APPROVED" }

使用 query-string 包:

import qs from "query-string";
const obj = qs.parse(this.props.location.search);
console.log(obj.param); // { limit: "10", page:"1", status:"APPROVED" } 

找不到包:

const convertToObject = (url) => {
  const arr = url.slice(1).split(/&|=/); // remove the "?", "&" and "="
  let params = {};

  for(let i = 0; i < arr.length; i += 2){
    const key = arr[i], value = arr[i + 1];
    params[key] = value ; // build the object = { limit: "10", page:"1", status:"APPROVED" }
  }
  return params;
};


const uri = this.props.location.search; // "?status=APPROVED&page=1&limit=20"

const obj = convertToObject(uri);

console.log(obj); // { limit: "10", page:"1", status:"APPROVED" }


// obj.status
// obj.page
// obj.limit
希望有所帮助 :)
愉快的编码!

4
阅读其他答案(首先是@duncan-finney,然后是@Marrs),我开始寻找更改日志,以解释惯用的react-router 2.x解决此问题的方式。在组件中使用位置(需要查询)的文档实际上与实际代码相矛盾。因此,如果您按照他们的建议,您将收到类似于以下的大怒警告:
Warning: [react-router] `context.location` is deprecated, please use a route component's `props.location` instead.

原来不能使用名为location的上下文属性,因为它使用了location类型。但是,可以使用名为loc的上下文属性,该属性使用location类型。因此,解决方案是对其源代码进行小修改,如下所示:
const RouteComponent = React.createClass({
    childContextTypes: {
        loc: PropTypes.location
    },

    getChildContext() {
        return { location: this.props.location }
    }
});

const ChildComponent = React.createClass({
    contextTypes: {
        loc: PropTypes.location
    },
    render() {
        console.log(this.context.loc);
        return(<div>this.context.loc.query</div>);
    }
});

您还可以仅传递您想要在子级中使用的位置对象的部分,从而获得相同的好处。它不会改变警告以更改为对象类型。希望这有所帮助。


3

简单的JavaScript解决方案:

queryStringParse = function(string) {
    let parsed = {}
    if(string != '') {
        string = string.substring(string.indexOf('?')+1)
        let p1 = string.split('&')
        p1.map(function(value) {
            let params = value.split('=')
            parsed[params[0]] = params[1]
        });
    }
    return parsed
}

您可以从任何地方使用以下方式进行调用:

var params = this.queryStringParse(this.props.location.search);

希望这有所帮助。

2
"react-router-dom": "6"

我可以通过useSearchParams获取页面属性的值。

let [searchParams, setSearchParams] = useSearchParams();

searchParams.get('page')

当你有一个像http://asd.com/report/7?page=3这样的URL时,你可以获取页面。完整的示例在这里:
 import React from 'react';
 import { useSearchParams} from "react-router-dom";
    
    const Detail = (props) => {
        const [searchParams, setSearchParams] = useSearchParams();
        console.log('page from search',searchParams.get('page')) // 1
        return (
            <div></div>
        );
    };
    
    export default Detail;

reactrouter


0
在使用query-string模块创建优化的产品生成时,您可能会遇到以下错误。

无法缩小来自此文件的代码: ./node_modules/query-string/index.js:8

为了克服这个问题,请使用另一个称为stringquery的替代模块,在运行构建时不会出现任何问题,可以很好地执行相同的过程。
import querySearch from "stringquery";

var query = querySearch(this.props.location.search);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接