首页 > 解决方案 > 无法导航到 / 并得到未定义的错误

问题描述

当我从 BookDetails 组件中删除一本书时,我得到一个未定义的错误 ==> book is undefined。我尝试使用导航钩子重定向到 ReadingList 组件,但仍然出现此错误。就像 BookDetails 组件仍然被渲染一样。

我在这里发布了codeSandbox。 https://codesandbox.io/s/reading-list-problem-suvz0?fbclid=IwAR3BSD8S92amT1i_Sgv6rO41rZnvwAO7vVg-940mC0hfSwAp9IwyCI0c49o

代码:

import React from "react";
import { Router } from "@reach/router";
import BookContextProvider from "./context/bookContext";

import ReadingList from "./components/reading-list/ReadingList";
import BookDetails from "./components/reading-list/BookDetails";

import "./App.css";

function App() {
  return (
    <div className="App">
      <BookContextProvider>
        <Router>
          <ReadingList path="/" />
          <BookDetails path="/books/:bookId" />
        </Router>
      </BookContextProvider>
    </div>
  );
}

export default App;

任何人都可以看看并给我一些帮助。

标签: reactjs

解决方案


这一切都是异步发生的,这意味着当书不存在时组件仍在尝试重新渲染。您可以在删除操作发生时通过返回null或其他占位符来解决此问题:

import React, { useContext } from "react";
import { bookContext } from "../../context/bookContext";
import { Link, useParams, useNavigate } from "@reach/router";
const BookDetails = () => {
  //! usParams() renvoie l'object :bookId ::<BookDetails path="/books/:bookId" /> compris dans l'url.
  const params = useParams();
  const navigate = useNavigate();

  const { books, deleteBook } = useContext(bookContext);
  const book = books.find(({ id }) => id.toString() === params.bookId);

  console.log(params);

  const handleDelete = () => {
    console.log(book.id);
    deleteBook(book.id);
    navigate("/");
  };

  if (!book) {
    return null;
  }

  return (
    <div className="wrapper">
      <h1>Book details : </h1>
      <h2>{book.title}</h2>
      <p>author : {book.author}</p>
      <button onClick={handleDelete}>delete book</button>
      <Link to="/">back to list</Link>
    </div>
  );
};

export default BookDetails;

或者,可能更好的是,您可以Redirect在 render 方法中使用book不存在的组件。这可能会更好,因为你会重定向回家,以防有人去了一个不存在的书籍路径,无论他们是否刚刚删除它。

import React, { useContext } from "react";
import { bookContext } from "../../context/bookContext";
import { Link, useParams, Redirect } from "@reach/router";
const BookDetails = () => {
  //! usParams() renvoie l'object :bookId ::<BookDetails path="/books/:bookId" /> compris dans l'url.
  const params = useParams();

  const { books, deleteBook } = useContext(bookContext);
  const book = books.find(({ id }) => id.toString() === params.bookId);

  const handleDelete = () => {
    console.log(book.id);
    deleteBook(book.id);
  };

  if (!book) {
    return <Redirect to="/" noThrow />;
  }

  return (
    <div className="wrapper">
      <h1>Book details : </h1>
      <h2>{book.title}</h2>
      <p>author : {book.author}</p>
      <button onClick={handleDelete}>delete book</button>
      <Link to="/">back to list</Link>
    </div>
  );
};

export default BookDetails;

推荐阅读