【问题标题】:React: Component name based on propReact:基于 prop 的组件名称
【发布时间】:2021-09-20 15:34:05
【问题描述】:

我正在尝试通过道具在 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>
    )
}

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

【问题讨论】:

    标签: javascript reactjs components


    【解决方案1】:

    这是一个工作版本:

    import * as Icons from "react-icons/fi";
    
    function Button(props) {
      const Icon = Icons[props.icon];
      return <button><Icon/></button>;
    }
    

    我在stackblitz上添加了一个例子

    【讨论】:

    • 这正是我想要的。谢谢!
    【解决方案2】:

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

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

    【讨论】:

    • 感谢您的帮助!按钮组件需要知道存在哪些图标。由于可能有成千上万种不同的语句,因此使用 if 或 switch 语句对我来说太多了。
    • 我至少会建议编写一些验证逻辑。否则,如果将无效的图标字符串传递给组件,则会出现错误。
    • 没错,我完全没有想到。好点子!但是,我认为这对我的用例来说已经足够了。
    • 为了完整起见,我添加了一个示例,说明如何进行一些验证。
    猜你喜欢
    • 1970-01-01
    • 2023-03-27
    • 1970-01-01
    • 2019-10-23
    • 1970-01-01
    • 2021-12-18
    • 2020-08-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多