You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何从Marvel API获取数据与图片?React路由及详情页开发问题

Solution for Marvel API + React Routing & Image Display Issues

Hey there! Let's work through your two key problems: getting route-based comic detail pages working and correctly rendering Marvel's comic images. I'll use your existing code as a base to show exactly what to change.

1. Set Up Routing to Comic Detail Pages

First, we need to add routing to your app and make comic thumbnails clickable links.

Step 1: Install React Router

If you haven't already, install react-router-dom:

npm install react-router-dom
# or
yarn add react-router-dom

Step 2: Configure Routes in Your Root Component

Update your root component (like App.js) to define routes for the home page and comic detail page:

import { BrowserRouter as Router, Routes, Route } from 'react-router-dom';
import Home from './components/Home';
import ComicInfo from './components/ComicInfo';

function App() {
  return (
    <Router>
      <Routes>
        <Route path="/" element={<Home />} />
        <Route path="/comic/:comicId" element={<ComicInfo />} />
      </Routes>
    </Router>
  );
}

export default App;

Step 3: Make Comic Thumbnails Clickable (Update Home Component)

Wrap your ComicThumb in a Link component to navigate to the detail page. We'll also simplify the image URL construction by building it directly in the map:

// Add this import at the top of Home.js
import { Link } from 'react-router-dom';

// ... keep your existing state and componentDidMount code ...

render() {
  const { comics } = this.state;

  return (
    <>
      <Header />
      <Searchbar />
      <ThreeColGrid>
        {comics.map((comic) => {
          // Build image URL directly for each comic
          const comicImage = `${comic.thumbnail.path}/${BACKDROP_SIZE}.${comic.thumbnail.extension}`;
          return (
            <Link key={comic.id} to={`/comic/${comic.id}`}>
              <ComicThumb clickable={true} image={comicImage} comicId={comic.id} />
            </Link>
          );
        })}
      </ThreeColGrid>
    </>
  );
}

Step 4: Fetch & Display Comic Details (Update ComicInfo Component)

Use React hooks to grab the comic ID from the URL, fetch detail data from the Marvel API, and render the content properly:

import React, { useState, useEffect } from 'react';
import { useParams } from 'react-router-dom';
import ComicThumb from '../ComicThumb';
import { POSTER_SIZE, API_URL, API_KEY, HASH } from '../helpers';

const ComicInfo = () => {
  const [comic, setComic] = useState(null);
  const [loading, setLoading] = useState(true);
  const { comicId } = useParams();

  useEffect(() => {
    const fetchComicDetails = async () => {
      try {
        const endpoint = `${API_URL}public/comics/${comicId}?ts=1&apikey=${API_KEY}&hash=${HASH}`;
        const result = await fetch(endpoint);
        const data = await result.json();
        setComic(data.data.results[0]);
      } catch (error) {
        console.error('Error fetching comic details:', error);
      } finally {
        setLoading(false);
      }
    };

    fetchComicDetails();
  }, [comicId]);

  if (loading) return <div>Loading comic details...</div>;
  if (!comic) return <div>Comic not found!</div>;

  // Build valid image URL per Marvel's rules
  const comicImage = `${comic.thumbnail.path}/${POSTER_SIZE}.${comic.thumbnail.extension}`;

  return (
    <div style={{ padding: '2rem' }}>
      <div style={{ display: 'flex', gap: '2rem', flexWrap: 'wrap' }}>
        <div>
          <ComicThumb image={comicImage} />
        </div>
        <div>
          <h1>{comic.title}</h1>
          <h3>Description:</h3>
          <p>{comic.description || 'No description available.'}</p>
          <p><strong>Page Count:</strong> {comic.pageCount}</p>
          <p><strong>On Sale Date:</strong> {comic.dates.find(d => d.type === 'onsaleDate')?.date.slice(0, 10)}</p>
        </div>
      </div>
    </div>
  );
};

export default ComicInfo;

2. Correctly Build Marvel Image URLs

Marvel's image system uses a consistent structure: [thumbnail.path]/[size].[thumbnail.extension]. Valid size modifiers include:

  • Portrait: portrait_small, portrait_medium, portrait_xlarge
  • Landscape: landscape_small, landscape_medium, landscape_incredible
  • Standard: standard_small, standard_medium, standard_large

Ensure your helpers.js uses valid values, for example:

export const BACKDROP_SIZE = 'landscape_incredible';
export const POSTER_SIZE = 'portrait_xlarge';

Invalid size strings will result in broken images, so stick to Marvel's documented options!

Quick Tips

  • Use the comic's id as the map key (instead of index) for better React performance.
  • Add error handling for API calls (like the try/catch in ComicInfo) to handle failed requests gracefully.
  • Double-check your ComicThumb component renders an <img> tag with the src prop set to the passed image URL.

内容的提问来源于stack exchange,提问作者Hervé

火山引擎 最新活动