React Router - Routing einrichten (Vereinfachte Version mit React Bootstrap)
In diesem Abschnitt richten wir das Routing mit React Router ein und verwenden ausschliesslich React Bootstrap-Komponenten ohne eigenes CSS.
1. React Router installieren
Abschnitt betitelt „1. React Router installieren“npm install react-router-dom2. AppRouter erstellen
Abschnitt betitelt „2. AppRouter erstellen“Änderung: Erstellen eines zentralen Routers, der die App als Layout-Komponente verwendet:
import { BrowserRouter as Router, Routes, Route } from "react-router-dom";import App from "./App";import HomePage from "./pages/HomePage/HomePage";import SearchPage from "./pages/SearchPage/SearchPage";import BookDetailsPage from "./pages/BookDetailsPage/BookDetailsPage";import FavoritesPage from "./pages/FavoritesPage/FavoritesPage";import NotFoundPage from "./pages/NotFoundPage/NotFoundPage";
function AppRouter() { return ( <Router> <Routes> <Route path="/" element={<App />}> <Route index element={<HomePage />} /> <Route path="search" element={<SearchPage />} /> <Route path="book/:id" element={<BookDetailsPage />} /> <Route path="favorites" element={<FavoritesPage />} /> <Route path="*" element={<NotFoundPage />} /> </Route> </Routes> </Router> );}
export default AppRouter;3. App.jsx als Layout-Komponente umbauen
Abschnitt betitelt „3. App.jsx als Layout-Komponente umbauen“Änderung: App.jsx wird zur Layout-Komponente mit Bootstrap Container und Outlet für die verschachtelten Routen:
import { Outlet } from "react-router-dom";import { Container } from "react-bootstrap";import Header from "./components/Header/Header";
function App() { return ( <div> <Header /> <Container className="py-4"> <Outlet /> </Container> <footer className="bg-light py-3 text-center"> <Container> <p className="text-muted mb-0"> © {new Date().getFullYear()} Bücher-Projekt </p> </Container> </footer> </div> );}
export default App;4. Header-Komponente mit React Bootstrap Navigation
Abschnitt betitelt „4. Header-Komponente mit React Bootstrap Navigation“Header-Komponente mit React Bootstrap Navbar und React Router’s NavLink für alle Seiten:
import { Navbar, Nav, Container } from "react-bootstrap";import { NavLink } from "react-router-dom";
function Header() { return ( <Navbar bg="light" expand="lg"> <Container> <Navbar.Brand as={NavLink} to="/"> 📚 Bücher-Projekt </Navbar.Brand> <Navbar.Toggle aria-controls="basic-navbar-nav" /> <Navbar.Collapse id="basic-navbar-nav"> <Nav className="ms-auto"> <Nav.Link as={NavLink} to="/" end> Startseite </Nav.Link> <Nav.Link as={NavLink} to="/search"> Bücher suchen </Nav.Link> <Nav.Link as={NavLink} to="/favorites"> Favoriten </Nav.Link> </Nav> </Navbar.Collapse> </Container> </Navbar> );}
export default Header;5. main.jsx aktualisieren
Abschnitt betitelt „5. main.jsx aktualisieren“Änderung: main.jsx aktualisieren, um AppRouter statt App zu rendern und Bootstrap CSS zu importieren:
import { StrictMode } from "react";import { createRoot } from "react-dom/client";import AppRouter from "./AppRouter";import "bootstrap/dist/css/bootstrap.min.css";import "./index.css";
createRoot(document.getElementById("root")).render( <StrictMode> <AppRouter /> </StrictMode>);6. BookCard-Komponente mit React Bootstrap und Routing
Abschnitt betitelt „6. BookCard-Komponente mit React Bootstrap und Routing“Änderung: BookCard mit React Bootstrap Card-Komponente und Link zur Detailseite:
import { useState } from "react";import { Card, Button, Badge } from "react-bootstrap";import { FaHeart, FaRegHeart, FaExternalLinkAlt } from "react-icons/fa";import { Link } from "react-router-dom";
function BookCard({ book }) { const { id, title, author, imageUrl, description, publishedDate, previewLink, } = book;
// State für den Favoriten-Status const [isFavorite, setIsFavorite] = useState(false);
// Funktion zum Umschalten des Favoriten-Status const toggleFavorite = (e) => { e.stopPropagation(); // Verhindert, dass der Link aktiviert wird e.preventDefault(); setIsFavorite(!isFavorite); };
// Standard-Bild, falls kein Bild-URL bereitgestellt wird const defaultImage = "https://placehold.co/128x192";
return ( <Card className="h-100"> <div className="d-flex flex-column flex-md-row"> <div style={{ flex: "0 0 128px" }}> <Card.Img src={imageUrl || defaultImage} alt={`Cover von ${title}`} style={{ height: "192px", objectFit: "cover" }} /> </div> <Card.Body> <Card.Title>{title}</Card.Title> <Card.Subtitle className="mb-2 text-muted">{author}</Card.Subtitle>
{publishedDate && ( <Badge bg="secondary" className="mb-2"> Veröffentlicht: {publishedDate} </Badge> )}
<Card.Text> {description ? description.length > 150 ? `${description.substring(0, 150)}...` : description : "Keine Beschreibung verfügbar"} </Card.Text>
<div className="d-flex gap-2 mt-auto"> <Button as={Link} to={`/book/${id}`} variant="primary"> Details </Button>
{previewLink && ( <Button variant="outline-primary" href={previewLink} target="_blank" rel="noopener noreferrer" > <FaExternalLinkAlt className="me-1" /> Vorschau </Button> )}
<Button variant={isFavorite ? "danger" : "outline-danger"} onClick={toggleFavorite} aria-label={ isFavorite ? "Aus Favoriten entfernen" : "Zu Favoriten hinzufügen" } > {isFavorite ? <FaHeart /> : <FaRegHeart />} </Button> </div> </Card.Body> </div> </Card> );}
export default BookCard;Zusammenfassung
Abschnitt betitelt „Zusammenfassung“In dieser vereinfachten Version haben wir:
- React Router eingerichtet für die Navigation zwischen verschiedenen Seiten
- Wichtige Routenstrukturen erstellt mit einer übersichtlichen Layout-Komponente
Im nächsten Schritte werden wir die Context API kennenlernen und in das Projekt integrieren.
Danke für Ihr Feedback!