1

我正在创建一个 React 网络应用程序,用于显示来自 API 的 Covid 数据。我在使用 React 路由时遇到问题。

在这里,您可以看到 react-router-dom 5.3.0 版和 6.0.0 版的更改文件。使用 5.3.0 版本注释的版本实际上正在运行,在主页组件中,我得到国家列表和一个按钮,该按钮链接到包含所选国家详细信息的详细信息页面。对于 ViewDetails 页面中的 6.0.0 版本,状态始终为空,我没有看到所选国家/地区的详细信息,我不明白如何解决这个问题。

应用程序.js

import React from "react";
import './App.css';
import Home from "./Home";
import ViewDetails from "./ViewDetails";
/*v6.0.0*/
import {  BrowserRouter, Routes, Route, Link} from "react-router-dom";
/*5.3.0
import { BrowserRouter, Route, Switch } from "react-router-dom";
*/

function App() {
return (

/* VERSION 5.3.0 
<BrowserRouter>
     <div>
       <Switch>
         <Route exact path="/" component={Home} />
          <Route
           exact
           path="/view-details/:id"
           component={ViewDetails}
         />
       </Switch>
     </div>
   </BrowserRouter>
*/

/* VERSION v6.0.0*/
<BrowserRouter>
  <Routes>
    <Route path="/" element={<Home />} />
    <Route path="/view-details/:id" element={<ViewDetails />} />
  </Routes>
</BrowserRouter>

  );
}

export default App;

主页.js

import React, { useState, useEffect } from "react";
import { Link } from "react-router-dom"
import Axios from "axios";
import { v4 as uuidv4 } from "uuid";
import '@fontsource/roboto/300.css';
import '@fontsource/roboto/400.css';
import '@fontsource/roboto/500.css';
import '@fontsource/roboto/700.css';
import Button from '@mui/material/Button';
import './styles/home.css'
import Box from '@mui/material/Box';
import List from '@mui/material/List';
import ListItem from '@mui/material/ListItem';
import ListItemButton from '@mui/material/ListItemButton';
import ListItemIcon from '@mui/material/ListItemIcon';
import ListItemText from '@mui/material/ListItemText';
import Divider from '@mui/material/Divider';
import { styled } from '@mui/material/styles';
import Grid from '@mui/material/Grid';
import Typography from '@mui/material/Typography';

const Home = props => {
    const [covidsData, setCovidData] = useState([]);
    const fetchCovidData = async () => {
    const { data } = await Axios.get(
      "https://corona.lmao.ninja/v2/countries?yesterday=&sort="
    );
    const covidData = data;
    for(let i=0; i < covidData.length; i++)
    {
        covidData[i]["id"] = uuidv4()
    }

    setCovidData(covidData);
    console.log(covidData);
  };

  useEffect(() => {
    fetchCovidData();
  }, []);
  

  /* SAME CODE FOR v5.3.0 AND v6.0.0 */
  return (
  <Grid container
  spacing={0}
  direction="column"
  alignItems="center"
  justifyContent="center"
  style={{ minHeight: '100vh' }}>
  <Typography variant="h1" component="h1">
    Covid data
    </Typography>
    <List>
      {covidsData.map(covidData => {
        return (
        <div key={covidData.id}>
        <ListItem >
            <ListItemText primary={covidData.country} />
            <Link className="link-details"
              to={{
                pathname: `/view-details/${covidData.id}`,
                state: { covidsData: covidData }
              }}
            >
      <Button style={{marginLeft: '0.5em', height:'1.8em'}} variant="contained">View</Button>
            </Link>
          </ListItem>
          <Divider />
          </div>
        );
      })}

    </List>
    </Grid>
  );

};

export default Home;

查看详细信息.js

import React from "react";
import { useLocation, Link } from "react-router-dom";
import Typography from '@mui/material/Typography';
import Button from '@mui/material/Button';
import './styles/viewdetails.css'

const ViewDetails = () => {

  /*SAME CODE FOR v5.3.0 AND v6.0.0 */
  const { state } = useLocation();
  console.log(state);
  

  return (
    <div>
    <Typography variant="h1" component="h1">
    Country: {state.covidsData.country}{" "}
    </Typography>
    <img
      src={state.covidsData.countryInfo.flag}
      alt="new"
      />
    <Typography variant="h2" component="h2">
    Today cases
    </Typography>
    <Typography variant="p" component="p">
    {state.covidsData.todayCases}
    </Typography>
      <Link to="/" className="back-to-list">
      <Button variant="contained">Back</Button>
      </Link>
    </div>
  );
};

export default ViewDetails;

当我使用 5.3.0 版本时,一切正常,我可以在 Home 和 ViewDetails 组件中看到数据。如果我安装 6.0.0 版,我会在 ViewDetails 页面中收到此错误:

TypeError: Cannot read properties of null (reading 'covidsData')
ViewDetails
F:/React/Cvid/cvid/src/ViewDetails.js:13
  10 | 
  11 |  return (
  12 |    <div>
> 13 | <Typography variant="h1" component="h1">
     | ^  14 | Country: {state.covidsData.country}{" "}
  15 | </Typography>
  16 | <img

如何切换到 react-router-dom 版本 6.0.0 并使 ViewDetails 页面再次工作?

谢谢你们。

4

1 回答 1

1

组件 API从react-router-dom Linkv5 更改为 v6。

关联

state现在是“顶级”道具。

interface LinkProps
  extends Omit<
    React.AnchorHTMLAttributes<HTMLAnchorElement>,
    "href"
  > {
  replace?: boolean;
  state?: State;
  to: To;
}

Home组件中,您只需将对象stateto对象上移到Link.

<List>
  {covidsData.map((covidData) => {
    return (
      <div key={covidData.id}>
        <ListItem>
          <ListItemText primary={covidData.country} />
          <Link
            className="link-details"
            to={`/view-details/${covidData.id}`}
            state={{ covidsData: covidData }} // <-- state is a prop
          >
            <Button
              style={{ marginLeft: "0.5em", height: "1.8em" }}
              variant="contained"
            >
              View
            </Button>
          </Link>
        </ListItem>
        <Divider />
      </div>
    );
  })}
</List>

编辑 react-routing-not-working-upgrading-from-v5-to-v6

于 2021-11-07T11:12:01.870 回答