React:基于 prop 的组件名称

React: Component name based on prop

我正在尝试通过 prop 在 React 中加载一个组件。是我想从父组件传过来的图标。

仪表板(父级):

import { Button } from './components';

function App() {
  return (
    <div className="app">
        <div className="app__nav">
            <Button icon="FiSun" />
            <Button icon="FiSun" />
        </div>
    </div>
  );
}

按钮(子):

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>
    )
}

不幸的是,我找不到一种简单的方法来完成这项工作,因为我不允许在组件名称中使用道具。

我怀疑这是你想要的模式。

如果 App 知道 Button 应该呈现的组件名称,那么您实际上并没有通过不传递组件引用本身来提供任何抽象。您也许可以像这样传递字符串,但我不建议走那条路。

相反,我会像这样将组件引用传递给 Button

import FiSun from '...';
...
<Button icon={FiSun} />
function Button(props) {
  const Icon = props.icon; // Alias as uppercase
  return(
    <button>
      <Icon />
    </button>
  )
}

或者如果您只希望 Button 组件知道可能的图标类型,我建议使用普通条件而不是尝试动态创建 JSX 标签:

function Button(props) {
  function renderIcon() {
    if (props.icon == 'FiSun') {
      return <FiSun />;
    } // else etc
  }

  return(
    <button>
      {renderIcon()}
    </button>
  )
}

为了在保持允许组件用户传入任何可用图标名称的功能的同时提供一些稳定性,您可以这样做:

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>
  )
}

这是一个工作版本:

import * as Icons from "react-icons/fi";

function Button(props) {
  const Icon = Icons[props.icon];
  return <button><Icon/></button>;
}

我在 stackblitz

上添加了一个示例