对于模型 "card" 的路径“_id”处的值 "undefined"(类型字符串),转换为 ObjectId 失败

Cast to ObjectId failed for value "undefined" (type string) at path "_id" for model "card"

我有一个带有卡片的网站,当您点击某些卡片时,您需要看到同一张卡片,但有不同的详细信息。但是每次我点击一些卡片时,我都会在终端中看到这个 massgae: 对于模型“card”的路径“_id”处的值“undefined”(类型字符串),转换为 ObjectId 失败

这是我写的:

** CardDatails.jsx**

import React, { Component } from "react";
import PageHeader from "../common/pageHeader";
import { getCard } from "../../services/cardService";

class CardDetails extends Component {
  state = {
    card: {
      adress: "",
      bizNumber: "",
      createdAt: "",
      description: "",
      image: { url: "", alt: "" },
      likes: [],
      phone: "",
      title: "",
    },
    errors: {},
    isMounted: false,
  };

  async componentDidMount() {
    try {
      const { data } = await getCard(this.props.id);
      this.setState({ card: { card: data, isMounted: true } });
    } catch (error) {
      this.setState({ errors: error.massage });
    }
  }

  render() {
    const { card } = this.state;
    const {
      title,
      description,
      image: { url, alt },
      address,
      phone,
      bizNumber,
      createdAt,
      likes,
    } = card;

    return (
      <React.Fragment>
        <PageHeader
          title={`Business Card of: ${title}`}
          subTitle={`Businness Description: ${description}`}
        />
        <div className="card-body p-2">
          <div>
            <img
              style={{ maxWidth: "400px" }}
              src={url}
              className="card-img"
              alt={alt}
            ></img>
            <br />
            <strong>Tel: </strong>
            {phone}
          </div>
          <div>
            <strong>Address: </strong>
            {address}
          </div>
          <div>
            <strong>Card Number: </strong>
            {bizNumber}
          </div>
          <div>
            <strong>Created At: </strong>
            {createdAt}
          </div>
          <div>
            <strong>likes: </strong>
            {likes}
          </div>
        </div>
      </React.Fragment>
    );
  }
}

export default CardDetails;

App.js:

import { useParams } from "react-router-dom";
import CardDetails from "./CardDetails";

const CardDetailsConvertor = () => {
  const { id } = useParams();
  return <CardDetails id={id} />;
};

export default CardDetailsConvertor;


import HomePage from "./layout/main/Home";
import About from "./layout/main/About.jsx";
import { Routes, Route } from "react-router-dom";
import Error404 from "./layout/main/Error404";
import Header from "./layout/header/Header.jsx";
import Footer from "./layout/footer/footer.jsx";
import BizSignup from "./layout/main/BizSignup";
import Logout from "./layout/main/Logout";
import MyCards from "./layout/main/MyCards";
import MyFavoriteCards from "./layout/main/MyFavoriteCards";
import Login from "./layout/main/Login";
import Signup from "./layout/main/Signup";
import { ToastContainer } from "react-toastify";
import "react-toastify/dist/ReactToastify.css";
import { getCurrentUser } from "./services/userService";
import CreateCard from "./layout/main/CreateCard";
import EditCardConvertor from "./layout/main/editCardConvertor";
import CardDetails from "./layout/main/CardDetails";
import CardDetailsConvertor from "./layout/main/CardDetailsConvertor";

function App() {
  const user = getCurrentUser();
  return (
    <div className="App">
      <Header user={user} />
      <ToastContainer />

      <main style={{ minHeight: "85vh" }}>
        <Routes>
          <Route path="/about" element={<About />} />
          <Route path="/biz-signup" element={<BizSignup />} />
          <Route path="/logout" element={<Logout />} />
          <Route path="/my-cards" element={<MyCards user={user} />} />
          <Route path="/create-card" element={<CreateCard user={user} />} />
          <Route
            path="/card-details-converotr"
            element={<CardDetailsConvertor user={user} />}
          />
          <Route
            path="/edit-card/:id"
            element={<EditCardConvertor user={user} />}
          />
          <Route path="/card-details/:id" element={<CardDetails />} />
          <Route
            path="/my-fav-cards"
            element={<MyFavoriteCards user={user} />}
          />
          <Route path="/login" element={<Login />} />
          <Route path="/signup" element={<Signup />} />
          <Route path="/" element={<HomePage />} />
          <Route path="*" element={<Error404 />} />
        </Routes>
      </main>

      <Footer />
    </div>
  );
}

export default App;




**CardDetailsConverotr.jsx:**
import { useParams } from "react-router-dom";
import CardDetails from "./CardDetails";

const CardDetailsConvertor = () => {
  const { id } = useParams();
  return <CardDetails id={id} />;
};

export default CardDetailsConvertor;

所以,如果你能帮上忙,我会很高兴 谢谢!

CardDetails 组件未传递任何属性,因此 this.props.id 未定义。

<Route
  path="/card-details/:id"
  element={<CardDetails />} // <-- no props are passed here
/>

您可以将 CardDetails 转换为功能组件,以便它可以使用 useParams 挂钩访问 id 路由参数,或者您可以创建自定义 withRouter 高阶组件来执行此操作并将参数作为要在组件中访问的道具注入。

我不会介绍转换,但下面是一个简单的withRouter HOC:

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

const withRouter = Component => props => {
  const params = useParams();
  return <Component {...props} params={params} />;
};

...

import React, { Component } from "react";
import PageHeader from "../common/pageHeader";
import { getCard } from "../../services/cardService";
import { withRouter } from "../path/to/withRouter";

class CardDetails extends Component {
  state = {
    ...
  };

  async componentDidMount() {
    try {
      const { data } = await getCard(this.props.params.id);
      this.setState({ card: { card: data, isMounted: true } });
    } catch (error) {
      this.setState({ errors: error.massage });
    }
  }

  render() {
    const { card } = this.state;
    const {
      title,
      description,
      image: { url, alt },
      address,
      phone,
      bizNumber,
      createdAt,
      likes,
    } = card;

    return (
      ...
    );
  }
}

export default withRouter(CardDetails);