收到TypeError:无法读取React中未定义的属性'location'

时间:2020-04-14 05:09:19

标签: reactjs ecmascript-6 react-router-dom

我正在学习React并试图绕过React路由器。我有一个将数据显示到表组件中的API,我想将项目名称用作URL参数。例如,如果国家/地区名称是USA,那么我想使用localhost:3000 / USA显示数据。我尝试实现此路由,但给出了错误。这是我的代码:

Index.js

import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import { BrowserRouter } from "react-router-dom";



ReactDOM.render(
  <BrowserRouter>
    <App />
  </BrowserRouter>
  ,
  document.getElementById('root')
);

App.js

import React, { Component } from 'react';
import Button from 'react-bootstrap/Button';
import Form from 'react-bootstrap/Form';
import Navbar from 'react-bootstrap/Navbar';
import Card from './Card';
import Loading from './Loading';
import Paginate from './Paginate';
import Result from './Result';
import {Switch, Route , Router} from 'react-router-dom'



export default class App extends Component {
  constructor() {
    super();
    this.state = {
      data: [],
      totalData: [],
      searchText: '',
      searchResult: [],
      isSearch: false,
      isLoading: true,
      pageSize: 8,
      currentPage: 1,
      showPaginate: true,

    }
    this.onSearchChange = this.onSearchChange.bind(this);
    this.handlePageChange = this.handlePageChange.bind(this);
  }

  //for displaying the data of all the countries
  componentDidMount() {
    const url =
      'https://corona.lmao.ninja/countries?sort=country'
    fetch(url)
      .then(result => result.json())
      .then(result => {
        //sorting by highest case
        var sortedData = result.sort((a, b) => b.cases - a.cases)
        this.setState({
          data: sortedData,
          isLoading: false
        })
      })

    //for displaying data in the card component
    const totalUrl =
      'https://corona.lmao.ninja/all'
    fetch(totalUrl)
      .then(result => result.json())
      .then(result => {
        //let store=result;
        //console.log("store data"+store)
        this.setState({

          totalData: result
        })
        console.log("2nd fetched data" + this.state.totalData)
      })
  }

  onSearchChange = (e) => {
    console.log("search change " + this.state.searchText)
    this.setState({
      searchText: e.target.value,
      isSearch: true,
      showPaginate: false,
    })
    console.log("api data" + this.state.data[0])
  }

  handlePageChange = (page) => {
    this.setState({
      currentPage: page
    })

  }
  render() {

    const indexOfLastItem = this.state.currentPage * this.state.pageSize;
    console.log("indexOfLastItem" + indexOfLastItem)
    const indexOfFirstItem = indexOfLastItem - this.state.pageSize;
    console.log("indexOfFirstItem" + indexOfFirstItem)
    const currentData = this.state.data.slice(indexOfFirstItem, indexOfLastItem);
    console.log("current data" + currentData)
    return (

      this.state.isLoading ? <Loading /> :
        <div id="main">
          <Router>
      <Switch>
          <Navbar bg="dark" variant="dark">
            <Navbar.Brand href="#home">
              <Button id="live_text"
              >Live</Button>
              <img
                alt=""
                src="/logo.svg"
                width="100"
                height="30"
                className="d-inline-block align-top"
              />{' '}
     Covid-19 dashboard

    </Navbar.Brand>
          </Navbar>


          <Card totalData={this.state.totalData} />

          <Form.Group>
            <Form.Control id="search_bar" value={this.state.searchText} onChange={this.onSearchChange} type="text" placeholder="Enter country" />
          </Form.Group>





          <Paginate
            dataCount={this.state.data.length}
            pageSize={this.state.pageSize}
            onPageChange={this.handlePageChange}
            currentPage={this.state.currentPage} />


          <Route path="/:id">
          <Result data={this.state.isSearch?this.state.data:currentData}
            searchCheck={this.state.isSearch}
            searchValue={this.state.searchText} />
          </Route>
        </Switch>
      </Router>

        </div>

    )
  }
}

Result.js

import React from 'react'
import Table from 'react-bootstrap/Table';
import {Switch, Route , Router, Link} from 'react-router-dom'

const Result = (props) => {
  console.log('props value is:' + props.data)
  let { searchCheck, searchValue } = props;

  let update = props.data.map((item) => {

    const { countryInfo, country, cases, deaths, recovered, active, casesPerOneMillion } = item;
    let findMortality=Math.ceil((deaths/cases)*100);
    return (
      <Router>
      (searchCheck) ? country.toUpperCase().includes(searchValue.toUpperCase()) ?
        <tbody>
          <tr key={countryInfo._id}>
            <td><img style={{ height: '25px', width: '50px' }} src={countryInfo.flag} /></td>

            <Link to={`${props.match.params.url}/${country}`}>{country}</Link>
            <td>{cases}</td>
            <td>{active}</td>
            <td>{recovered}</td>
            <th>{findMortality}%</th>
            <td>{deaths}</td>
          </tr>
        </tbody> :
        '' :
        <tbody>
          <tr key={countryInfo._id}>
            <td><img style={{ height: '25px', width: '50px' }} src={countryInfo.flag} /></td>
            <Link to={`${props.match.params.url}/${country}`}>{country}</Link>
            <td>{cases}</td>
            <td>{active}</td>
            <td>{recovered}</td>
            <th>{findMortality}%</th>
            <td>{deaths}</td>
          </tr>
        </tbody>
        <Switch>

        <Route path={`${props.match.params.url.path}/:country`}>
          <Country />
        </Route>
      </Switch>
     </Router>
    )
  })
  return (
    <div>
      <Table striped bordered hover variant="dark">
        <thead>
          <tr>

            <th>Flag</th>
            <th>Country</th>
            <th>Cases</th>
            <th>Active</th>
            <th>Recovered</th>
            <th>Mortality</th>
            <th>Deaths</th>


          </tr>
        </thead>
        {update}
      </Table>
    </div>
  )
}

function Country(props) {
  // The <Route> that rendered this component has a
  // path of `/topics/:topicId`. The `:topicId` portion
  // of the URL indicates a placeholder that we can
  // get from `useParams()`.
  //let { topicId } = useParams();

  return (
    <div>
      <h3>{props.match.params.country}</h3>
    </div>
  );
}

export default Result;

0 个答案:

没有答案