You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ReactJS如何将本地JSON动态导入图片与API动态获取数据匹配

问题原因

你当前在RaceCard组件内对完整的images数组做了全量遍历渲染,所以每张卡片都会展示所有本地图片,只需要根据当前卡片对应的种族标识,匹配到对应slug的单张图片即可。

解决方案

DnD5e 开放API返回的种族数据中默认带有index字段,取值和你imagedata.json里的slug完全一致,我们可以用这个字段做匹配关联,两种实现方式可选:

方案1:直接在卡片组件内匹配(改动最小)

修改RaceCard组件代码,先匹配对应图片再渲染,不要遍历全部图片:

import React from 'react';
import Markdown from 'markdown-to-jsx';
import * as C from './styles';

import images from '../../imagedata.json';

const RaceCard = ({ data }) => {
    // 匹配当前种族对应的图片
    const currentImage = images.find(img => img.slug === data.index);
    return (
        <C.Container>
            <C.Card
                id={data.name}
            >
                <C.Content>
                    <C.Title>
                        {data.name}
                    </C.Title>
                    <C.Text>
                        <Markdown>{data.desc}</Markdown>
                    </C.Text>
                    <C.Button>
                        Read More
                    </C.Button>
                </C.Content>
                {/* 只渲染匹配到的单张图片,匹配失败可显示占位图 */}
                {currentImage ? (
                    <C.Image
                        key={currentImage.id}
                        imgsrc={currentImage.imgsrc}
                        slug={currentImage.slug}
                    >
                        <img src={currentImage.imgsrc} alt={data.name} />
                    </C.Image>
                ) : (
                    // 可替换为你自己的占位图
                    <div>暂无图片</div>
                )}
            </C.Card>
        </C.Container>
    );
};

export default RaceCard;

如果你的API返回数据没有index字段,可以把匹配条件替换为处理后的name:img => img.slug === data.name.toLowerCase().replace(/\s+/g, '-')

方案2:父组件预关联数据(性能更优)

如果卡片数量较多,在父组件提前把图片和种族数据做关联,避免每个卡片都重复遍历图片数组:
首先修改Races组件:

import React, { useEffect, useState, useMemo } from 'react';
import * as C from './styles';

import api from '../../helpers/dnd5eAPI';
import images from '../../imagedata.json';

import { Theme } from '../../components/Theme';
import RaceCard from '../../components/RaceCard';

export const Races = () => {
    const [races, setRaces] = useState([]);
    // 预生成slug到图片路径的映射表
    const imageMap = useMemo(() => {
        return images.reduce((map, img) => {
            map[img.slug] = img;
            return map;
        }, {});
    }, []);

    useEffect(() => {
        const getRaces = async () => {
            const race = await api.getRaces();
            // 给每个种族数据附加对应图片信息
            const racesWithImg = race.results.map(item => ({
                ...item,
                image: imageMap[item.index] || null
            }));
            setRaces(racesWithImg);
        };
        getRaces();
    }, [imageMap]);

    return (
        <Theme>
            <C.Container>
                {races.map((item, index) => (
                    <RaceCard
                        key={index}
                        data={item}
                    />
                ))}
            </C.Container>
        </Theme>
    );
};

之后在RaceCard组件里直接使用附加的image字段即可:

// RaceCard组件内无需再导入images数组
const RaceCard = ({ data }) => {
    return (
        {/* 其他代码不变 */}
        {data.image && (
            <C.Image
                imgsrc={data.image.imgsrc}
                slug={data.image.slug}
            >
                <img src={data.image.imgsrc} alt={data.name} />
            </C.Image>
        )}
    )
}

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.28 07:06:04