Estoy tratando de cargar un componente en React a través de un accesorio. Es un icono que quiero pasar del componente principal.
Tablero (padre):
import { Button } from './components'; function App() { return ( <div className="app"> <div className="app__nav"> <Button icon="FiSun" /> <Button icon="FiSun" /> </div> </div> ); }Botón (niño):
import React from 'react'; import * as Icon from "react-icons/fi"; import './button.scss'; function Button(props) { return( <button> // Something like this <Icon.props.icon /> </button> ) }Desafortunadamente, no puedo encontrar una manera fácil de hacer que esto funcione ya que no puedo usar accesorios en el nombre del componente.
Aquí hay una versión de trabajo:
import * as Icons from "react-icons/fi"; function Button(props) { const Icon = Icons[props.icon]; return <button><Icon/></button>; }Agregué un ejemplo en stackblitz
Dudo que este sea el patrón que quieres.
Si la App conoce el nombre del componente que debe representar el Button , realmente no está proporcionando ninguna abstracción al no pasar la referencia del componente en sí. Es posible que pueda hacer que funcione pasando la cadena de esta manera, pero no recomendaría seguir esa ruta.
En su lugar, pasaría la referencia del componente a Button de esta manera:
import FiSun from '...'; ... <Button icon={FiSun} /> function Button(props) { const Icon = props.icon; // Alias as uppercase return( <button> <Icon /> </button> ) } O si desea que solo el componente Button conozca los posibles tipos de íconos, sugeriría usar un condicional normal en lugar de intentar crear dinámicamente la etiqueta JSX:
function Button(props) { function renderIcon() { if (props.icon == 'FiSun') { return <FiSun />; } // else etc } return( <button> {renderIcon()} </button> ) }Para proporcionar algo de estabilidad y al mismo tiempo mantener la funcionalidad de permitir que el usuario del componente pase cualquier nombre de icono disponible, podría hacer algo como esto:
function Button(props) { function renderIcon() { const I = Icon[props.icon]; if (I) { return <I />; } // Icon is not valid, throw error or use fallback. if (in_development) { console.error('[Button]: Invalid prop `icon`. Icon '+props.icon+' does not exist.'); } return <FallbackIcon /> } return( <button> {renderIcon()} </button> ) }