开发者问题收集

未捕获的类型错误:使用 axios 和 react-router-dom 时无法读取未定义的属性(读取‘params’)

2022-06-30
1000

这是 ReactJS 的 HomePage 组件

  import React from 'react';
  import axios from 'axios';
  import { useState, useEffect } from 'react';
  import { useNavigate,useParams } from 'react-router-dom';
  import { Main } from '../components/Main';
  import { Controls } from '../components/Controls';
  import { ALL_COUNTRIES } from '../config';
  import { List } from '../components/List';
  import { Card } from '../components/Card';
  import { Details } from './Details';

  export const HomePage = () => {
     const [countries,setCountries] = useState([]);
     const  navigate = useNavigate();

 useEffect(() => {
 axios.get(ALL_COUNTRIES).then(({data})=>setCountries(data))
 },[]);

  return (
     <>
     <Controls/>
     <List>
       {
       countries.map((c) => {
        const countryInfo = {
          img: c.flags.png,
          name: c.name,
          info: [
            {
              title:'Population',
              description:c.population.toLocaleString(),
            },
            {
              title:'Region',
              description:c.region,
            },
            {
              title:'Flag',
              description:c.capital,
            },
          ],
        };
        return (
          <Card
            key={c.name}
            onClick={(e) => {
              navigate('/country/${c.name}');
            }} 
            {...countryInfo}
          />
        )
      })
     }
    </List>
  </>
  );
 };

这是第二个组件 详细信息

  import React from 'react';
  import { useParams } from 'react-router-dom';
  export const Details = ({match,params}) => {
   const { name } = useParams();
    return (
       <div>
         Details {match.params.name}  
       </div>
      );
     };

config.js

 const BASE_URL = 'https://restcountries.com/v2/';
 export const ALL_COUNTRIES=BASE_URL+"all?fields=name,flags,population,capital,region";
 export const searchByContry=(name)=>BASE_URL+'name/'+name;
 export const filterByCode=(code)=>BASE_URL+'alpha?code'+code.join('');

APP.jsx

 import React from 'react';
 import ReactDOM from 'react-dom';
 import axios from 'axios';
 import { Route,Routes,Router,useParams} from 'react-router-dom';
 import {useState, useEffect} from 'react';
 import './App.css';
 import styled from 'styled-components';
 import Header from './components/Header';
 import { Main } from './components/Main';
 import {NotFound} from './pages/NotFound';
 import { HomePage } from './pages/HomePage';
 import { Details } from './pages/Details';
 function App() {

   return (
     <> 
       <Header/>
       <Main>
        <Routes>
        <Route path="/" element={<HomePage/>}/>
        <Route path="country/:name" element={<Details/>}/>
        <Route path="*" element={<NotFound/>}/>
      </Routes>
    </Main>
  </>
 );
 }

 export default App;

HomePage 本身看起来像这样 但是当我点击标志/卡片时,它会按预期将我发送到第二页,但会出现此错误 [2]: https://i.sstatic.net/39HEw.png 此外,我正在使用 react-router-domV6 和 Axios 以及此 API https://restcountries.com/v2/all 两个组件也都在 APP.js 中

1个回答

Details 尝试从未定义的对象(本例中为 props.match )读取 params

<Route path="country/:name" element={<Details />} /> // <-- no props passed!

...

import React from 'react';
import { useParams } from 'react-router-dom';

export const Details = ({ match, params }) => { // <-- match undefined
  const { name } = useParams();
  return (
    <div>
      Details {match.params.name} // <-- Oops, can't read params of undefined
    </div>
  );
};

删除 props 并访问从 useParams 钩子返回的值。

import React from 'react';
import { useParams } from 'react-router-dom';

export const Details = () => {
  const { name } = useParams();
  return (
    <div>
      Details {name}
    </div>
  );
};

目标路径也格式错误。代码 navigate('/country/${c.name}') 导航到字符串文字 "/country/${c.name}" ,这可能不是您想要执行的操作。修复此问题,改为使用字符串模板文字将 c.name 值注入目标路径。

navigate(`/country/${c.name}`) // note the backticks instead of single quotes

我经常发现使用 generatePath 实用函数来创建路径值很有用。

示例:

import { generatePath, useNavigate } from 'react-router-dom';

...

const path = generatePath("/country/:name", { name: c.name });
navigate(path);
Drew Reese
2022-06-30