我正在学习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;