React项目中加密货币SVG图标动态设置src不显示及require动态路径加载失败问题
Hey there! I've run into this exact issue with Webpack and dynamic asset loading in React before—let's break down why your icons aren't showing up and fix it.
The Root Problem
Webpack needs to know all your static asset paths at build time to bundle them correctly. When you use a dynamic template string like require(${temp[0]["src"]}), Webpack can't resolve the actual file path during compilation (since it only gets resolved at runtime). That's why you're seeing the "module not found" error.
Solution 1: Pre-Resolve Icons in Your JS File
Instead of storing raw string paths in cryptoIconSrc, use require() directly when defining your icon sources. This lets Webpack pick up the assets during build.
First, convert your cryptoIconSrc.json to a JavaScript file (since JSON can't execute require):
// cryptoIconSrc.js export default [ { symbol: "BTC", src: require("./path/to/btc.svg") // Replace with your actual icon path }, { symbol: "ETH", src: require("./path/to/eth.svg") }, // Add other crypto entries here ];
Then update your component code to use this pre-resolved source:
import cryptoIconSrc from './cryptoIconSrc.js'; // Inside your component's render/JSX currency.map((item) => { // Use find() instead of filter() to get a single match const matchedIcon = cryptoIconSrc.find(icon => icon.symbol === item.baseAsset); return ( <tr key={item.baseAsset}> <td> {/* Only render the img if we found a matching icon */} {matchedIcon && ( <img src={matchedIcon.src} width="20px" height="20px" alt={`${item.baseAsset} icon`} /> )} </td> {/* Rest of your table cells */} </tr> ); });
Solution 2: Use require.context for Bulk Icon Loading
If you have a lot of icons and want to avoid manually writing require for each one, use Webpack's require.context to load all icons in a directory automatically.
// Inside your component // Create a context that loads all SVG files in your icons directory const iconContext = require.context('./path/to/icons', false, /\.svg$/); // Build a map of symbol to icon source (assuming icon filenames match symbols, e.g., btc.svg for BTC) const iconMap = {}; iconContext.keys().forEach(filePath => { // Extract the symbol from the filename (e.g., "./btc.svg" → "BTC") const symbol = filePath .replace('./', '') .replace('.svg', '') .toUpperCase(); iconMap[symbol] = iconContext(filePath); }); // Then use it in your map function currency.map((item) => { const iconSrc = iconMap[item.baseAsset]; return ( <tr key={item.baseAsset}> <td> {iconSrc && ( <img src={iconSrc} width="20px" height="20px" alt={`${item.baseAsset} icon`} /> )} </td> {/* Rest of your table cells */} </tr> ); });
Key Notes
- Always handle cases where no icon matches (using
&&to conditionally render) to avoid errors from accessingtemp[0]when there's no match. - Double-check that your
symbolvalues incryptoIconSrcexactly match thebaseAssetvalues from your API (case sensitivity matters!). - If you're using Create React App, this approach works out of the box—no extra Webpack config needed.
内容的提问来源于stack exchange,提问作者hossein fti

