【问题标题】:Getting query parameters from react-router hash fragment从 react-router 哈希片段获取查询参数
【发布时间】:2015-07-03 09:11:38
【问题描述】:

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

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

我的路线运行良好,但我只是不确定如何格式化路径以获取我想要的参数。感谢您对此的任何帮助!

【问题讨论】:

标签: javascript reactjs client-side react-router client-side-scripting


【解决方案1】:

注意:从评论中复制/粘贴。一定要喜欢原帖!

用 es6 编写并使用 react 0.14.6 / react-router 2.0.0-rc5。我使用这个命令在我的组件中查找查询参数:

this.props.location.query

它在 url 中创建所有可用查询参数的哈希。

更新:

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

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

【讨论】:

【解决方案2】:

以上答案不适用于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

【讨论】:

  • 或者没有 lib:const query = new URLSearchParams(props.location.search); console.log(query.get('hello'));(旧浏览器需要 polyfill)。
  • 这应该在我构建应用程序时工作,对吧?
【解决方案3】:

旧(前 v4):

用 es6 编写并使用 react 0.14.6 / react-router 2.0.0-rc5。我使用这个命令在我的组件中查找查询参数:

this.props.location.query

它在 url 中创建所有可用查询参数的哈希。

更新(反应路由器 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

【讨论】:

  • 我已经用 React 0.14.8 进行了测试,但你的答案无法渲染:错误:TypeError: Cannot read property 'location' of undefined :|
  • 嘿@ThomasModeneis,这是您的路由器正在渲染的最顶层父组件吗?或者它是一个子组件?如果我没记错的话,您必须将 this.props.location.query 从路由器渲染的父组件传递给您的子组件,这是我唯一能想到的。
【解决方案4】:

更新 2017.12.25

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

网址喜欢

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&amp;age=26

const queryParams = this.props.location.query;

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

【讨论】:

  • 如果你有这样的事情:http://localhost:8090/#access_token=PGqsashgJdrZoU6hV8mWAzwlXkJZO8ImDcn&amp;expires_in=7200&amp;token_type=bearer(即#之后没有/)那么对于反应路由器v4你应该使用location.hash而不是location.search
【解决方案5】:
"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'); //

【讨论】:

    【解决方案6】:

    带字符串查询包:

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

    带有查询字符串包:

    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
    

    希望有帮助:)

    编码愉快!

    【讨论】:

      【解决方案7】:

      在阅读了其他答案(首先是@duncan-finney,然后是@Marrs)之后,我着手查找更改日志,该日志解释了解决此问题的惯用 react-router 2.x 方法。组件中的documentation on using location(您需要查询)实际上与实际代码相矛盾。所以如果你听从他们的建议,你会收到这样的愤怒警告:

      Warning: [react-router] `context.location` is deprecated, please use a route component's `props.location` instead.
      

      事实证明,您不能有一个名为 location 的上下文属性使用 location 类型。但是您可以使用一个名为 loc 的上下文属性,它使用位置类型。所以解决方案是对它们的源进行小修改,如下所示:

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

      您也可以只将您想要的位置对象部分传递给您的孩子,从而获得相同的好处。它没有更改警告以更改为对象类型。希望对您有所帮助。

      【讨论】:

        【解决方案8】:

        简单的js解决方案:

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

        希望这会有所帮助。

        【讨论】:

          【解决方案9】:

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

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

          要克服这个问题,请使用名为 stringquery 的替代模块,它可以很好地完成相同的过程,在运行构建时不会出现任何问题。

          import querySearch from "stringquery";
          
          var query = querySearch(this.props.location.search);
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2021-10-25
            • 1970-01-01
            • 2010-12-19
            • 2017-08-30
            • 2019-11-09
            • 1970-01-01
            • 1970-01-01
            • 2011-01-20
            相关资源
            最近更新 更多