基于styled-components的通用React图标组件问题排查:无法通过Props传递图标名称
Let's break down what's causing your component to fail, then walk through a solution that supports both react-icons components and local SVG files while keeping your size/color props working.
What's Wrong With Your Current Code
- Hardcoded Icon Component: Your
StyledSVGIconis directly styledFaUserTie—no matter whatnameprop you pass, it will always render this specific icon. - Invalid Prop for React Icons: You're passing a
srcprop toStyledSVGIcon, but react-icons components don't usesrc—they're React components, not external SVG files loaded via URL. - No Dynamic Component Resolution: There's no logic to map your
nameprop string to the actual react-icons component you want to use.
Solution: Support Both React Icons and Local SVGs
We'll build a component that:
- Maps icon names to react-icons components
- Handles both react-icons and local SVG files
- Preserves your size/color/transform prop functionality
Step 1: Create an Icon Component Map
First, import all the react-icons you want to use and map them to their string names. This lets us convert the name prop into a usable component.
Step 2: Build Styled Components for Both Icon Types
We'll create separate styled components for react-icons and local SVGs, since they need different styling approaches.
Step 3: Add Logic to Render the Correct Icon Type
In the GenIcon component, we'll check if the name exists in our react-icons map. If it does, we render the styled react-icon; if not, we assume it's a local SVG file and use ReactSVG.
Full Modified Code
import React from "react"; import { ReactSVG } from "react-svg"; import styled, { css } from "styled-components"; // Import all the react-icons you want to support import { FaUserTie, FaUserNurse } from 'react-icons/fa'; // 1. Create a map of icon names to their react-icons components const ReactIconMap = { FaUserTie, FaUserNurse, // Add more icons here as needed }; // 2. Styled component for react-icons const StyledReactIcon = styled(({ iconComponent, ...props }) => React.createElement(iconComponent, props))` ${({ size }) => size && css` width: ${size}; height: ${size}; `} ${({ transform }) => transform && css` transform: ${transform}; `} ${({ color }) => color && css` color: ${color}; /* react-icons use color prop directly, but some might need fill—adjust if needed */ fill: ${color}; `} `; // 3. Styled component for local SVG files const StyledLocalSVG = styled(ReactSVG)` svg { fill: black; ${({ size }) => size && css` width: ${size}; height: ${size}; `} ${({ transform }) => transform && css` transform: ${transform}; `} path { ${({ color }) => color && css` fill: ${color}; `} } } `; const GenIcon = ({ name, color, size, transform, ...rest }) => { // Check if the name is in our react-icons map const ReactIconComponent = ReactIconMap[name]; if (ReactIconComponent) { // Render the styled react-icon return ( <StyledReactIcon iconComponent={ReactIconComponent} color={color} size={size} transform={transform} {...rest} /> ); } else { // Render local SVG file if name isn't in the map return ( <StyledLocalSVG src={`/icons/${name}.svg`} color={color} size={size} transform={transform} {...rest} /> ); } }; export default GenIcon;
How to Use It
Now your component will work for both react-icons and local SVGs:
// Use a react-icon from your map <GenIcon name="FaUserNurse" color="red" size="16px" /> // Use a local SVG file (assumes /icons/user.svg exists) <GenIcon name="user" color="blue" size="24px" />
Key Notes
- Adding More React Icons: Just import them and add them to the
ReactIconMapobject with their exact name as the key. - Styling Adjustments: Some react-icons might use
colorinstead offill—the styled component handles both, but you can tweak it if needed for specific icons. - Local SVG Path: Make sure your local SVGs are placed in the correct public directory so the
srcpath works (e.g.,/icons/in the public folder of your React app).
内容的提问来源于stack exchange,提问作者Anees Ahmad

