无法从查询字符串读取params属性?

时间:2019-01-16 13:51:33

标签: reactjs

我有一个简单的应用程序,可以访问opentable api(http://opentable.herokuapp.com/api/restaurants)。我的应用程序在加载时仅显示查询参数中指定的内容。例如,附加?city=toronto将为我提供多伦多的所有餐馆。这是一个有效的硬编码示例:

import React, { Component } from "react";
import Spinner from "./components/common/Spinner";

class App extends Component {
  constructor(props) {
    super(props);
    this.state = {
      items: [],
      isLoading: false
    };
  }

  componentDidMount() {
    // // let city = this.props.match.params.city;
    // // console.log(city);
    // console.log(this.props.match.params.city);
    fetch("http://opentable.herokuapp.com/api/restaurants?city=Toronto")
      .then(res => res.json())
      .then(json => {
        this.setState({
          isLoading: true,
          items: json
        });
      });
  }
  render() {
    const { isLoading, items } = this.state;
    let itemsToArray = Object.values(items);
    return !isLoading ? (
      <div>
        <Spinner />
      </div>
    ) : (
      <div className="App">
        <ul>
          {itemsToArray[3].map(item => (
            <div>
              <li key={item.id}>{item.name}</li>
            </div>
          ))}
        </ul>
      </div>
    );
  }
}

export default App;

如果我取消注释console.log(this.props.match.params.city);,则会抛出错误TypeError: Cannot read property 'params' of undefined。我访问参数不正确吗?我想做类似的事情,

componentDidMount() {
  let city = this.props.match.params.city;
  fetch(`http://opentable.herokuapp.com/api/restaurants?city=${city}`)
    .then(...

3 个答案:

答案 0 :(得分:2)

如果您尝试使用以下内容:

http://myapp/page?city=Toronto

然后,this.props.match.params.city将不起作用。原因是match.params.city的用例应该在路由中。

import { Route } from "react-router-dom";

<Route path="/path/:city" component={App} />

在您的componentDidMount()生命周期方法中,尝试使用:

const urlParams = new URLSearchParams(window.location.search);
let city = urlParams.get('city');

对于上述代码,请查看How can I get query string values in JavaScript?在您的代码中,如果您尝试记录city的值,那么如果您尚未配置路由,则可能是undefined这样。

示例代码

class App extends React.Component {
  state = {
    city: "None"
  };
  componentDidMount() {
    const urlParams = new URLSearchParams(window.location.search);
    let city = urlParams.get("city");
    this.setState({
      city
    });
    console.log(city);
  }
  render() {
    return (
      <div className="App">
        <h1>Hello CodeSandbox</h1>
        <h2>Start editing to see some magic happen!</h2>
        <h3>You are in {this.state.city}!</h3>
      </div>
    );
  }
}

工作演示: CodeSandbox

答案 1 :(得分:0)

您可以使用此功能访问URL参数

var getParams = function (url) {   
    var params = {};
    var parser = document.createElement('a');
    parser.href = url;
    var query = parser.search.substring(1);
    var vars = query.split('&');
    if(vars == ''){
        params = '';
        return params;
    }
    for (var i = 0; i < vars.length; i++) {
        var pair = vars[i].split('=');
        params[pair[0]] = decodeURIComponent(pair[1]);
    }
    return params;
};

并命名为

console.log(getParams(window.location.href));

答案 2 :(得分:0)

如果尝试用App包装withRouter类组件怎么办?因此,它将如下所示:

import React, { Component } from "react";
import { withRouter } from 'react-router-dom';
import Spinner from "./components/common/Spinner";

class App extends Component {
  //....
}

export default withRouter(App);