如何在 React 中将组件作为 Props 传递?让我们来编码

2025-05-24

如何在 React 中将组件作为 Props 传递

让我们开始编码

概述

让组件可复用的方法之一是传递 props,无论它们是字符串、整数、布尔值、对象、数组等等。但最终你需要复用组件,而你唯一需要修改的就是例如 header 部分。

最常用的方式是使用children,也就是说,你会有一个父组件,它有一个开始和结束标签。如果你只需要更改一个组件,则无需执行任何其他操作,但是如果你需要传递多个组件,情况就有所不同。

为此,理想的情况是拥有一个带有自闭合标签的父组件,如果在 props 中传递了子组件,则该标签会呈现子组件。

今天的例子

今天我们要创建三个完全不同的按钮,一个左边有图标,一个没有图标,一个右边有图标。

但是,我们将重用相同的组件,并通过道具来改变图标的​​位置和按钮的背景颜色。

此外,您可能已经知道,图标将作为道具传递。

让我们开始编码

让我们安装以下依赖项:

npm install classnames react-icons
Enter fullscreen mode Exit fullscreen mode

此应用程序中的所有组件样式都将使用CSS 模块完成,并且我将使用类名依赖关系通过条件将它们连接起来

首先,让我们开始处理即将复用的组件。首先,我们来设计按钮的样式。按钮将拥有两种背景颜色(主色和普通色)。此外,我们还需要更改按钮元素的位置,为此,我们将使用一个简单的 flex 方向反转来反转元素的顺序。最后,同样重要的是,我们将根据图标的位置为其添加间距。

/* @src/components/Button.module.css */

.button {
  display: flex;
  flex-direction: row;
  align-items: center;
  margin: 20px 0px;
  cursor: pointer;
  font-weight: 500;
  padding: 13px 25px;
  border-radius: 15px;
  font-size: 1rem;
  border: none;
  color: #fff;
  transition: all 0.25s ease;
}

.button:hover {
  transform: translateY(-5px);
}

.reverse {
  flex-direction: row-reverse;
}

.primaryBG {
  background: #185adb;
}

.primaryBG:hover {
  box-shadow: 0 10px 20px -10px rgba(24, 90, 219, 0.6);
}

.normalBG {
  background: #363449;
}

.normalBG:hover {
  box-shadow: 0 10px 20px -10px rgba(54, 52, 73, 0.6);
}

.icon {
  margin-bottom: -5px;
  margin-right: 6px;
  margin-left: 0px;
}

.iconRight {
  margin-right: 0px;
  margin-left: 6px;
}
Enter fullscreen mode Exit fullscreen mode

现在我们可以开始处理我们的 Web 组件了。

// @src/components/Button.jsx

import React from "react";
import classNames from "classnames";

import styles from "./Button.module.css";

const Button = () => {
  return (
    // ...
  );
};

export default Button;
Enter fullscreen mode Exit fullscreen mode

现在让我们定义我们将在组件中接收的道具:

  • 图标——将是图标组件;
  • hasIconRight - 是一个布尔值,用于判断图标是否放置在右侧;
  • title——将是一个字符串,其值为我们想要在按钮中显示的内容;
  • onClick - 是在点击事件时触发的函数;
  • primary - 是一个布尔值,表示按钮的背景颜色应该是主要颜色;

在我们的按钮上,首先我们将应用基本样式,然后设置两个条件。如果组件接收到primary属性,则按钮将使用 primary 颜色作为背景颜色,否则将使用正常颜色。

第二个条件是按钮元素的放置,如果接收到 prop hasIconRight,则元素的放置将被反转(在这种情况下按钮将转到右侧)。

// @src/components/Button.jsx

import React from "react";
import classNames from "classnames";

import styles from "./Button.module.css";

const Button = ({ icon, hasIconRight, title, onClick, primary }) => {
  return (
    <button
      className={classNames([
        styles.button,
        primary ? styles.primaryBG : styles.normalBG,
        hasIconRight && styles.reverse,
      ])}
    >
     // ...
    </button>
  );
};

export default Button;
Enter fullscreen mode Exit fullscreen mode

现在我们来处理图标。如果它传入了 props,我们就会渲染它,否则我们不希望它占用 DOM 空间。之后,我们会将基础样式传递给图标包装器,并且我们还会设置一个条件:如果接收到hasIconRight prop,我们希望应用理想的间距。

// @src/components/Button.jsx

import React from "react";
import classNames from "classnames";

import styles from "./Button.module.css";

const Button = ({ icon, hasIconRight, title, onClick, primary }) => {
  return (
    <button
      className={classNames([
        styles.button,
        primary ? styles.primaryBG : styles.normalBG,
        hasIconRight && styles.reverse,
      ])}
    >
      {!!icon && (
        <span
          className={classNames([
            styles.icon,
            hasIconRight && styles.iconRight,
          ])}
        >
          {icon}
        </span>
      )}
      // ...
    </button>
  );
};

export default Button;
Enter fullscreen mode Exit fullscreen mode

最后,只需添加标题,以便按钮具有一些文本内容,我们将onClick属性传递给按钮的标签。

// @src/components/Button.jsx

import React from "react";
import classNames from "classnames";

import styles from "./Button.module.css";

const Button = ({ icon, hasIconRight, title, onClick, primary }) => {
  return (
    <button
      className={classNames([
        styles.button,
        primary ? styles.primaryBG : styles.normalBG,
        hasIconRight && styles.reverse,
      ])}
      onClick={onClick}
    >
      {!!icon && (
        <span
          className={classNames([
            styles.icon,
            hasIconRight && styles.iconRight,
          ])}
        >
          {icon}
        </span>
      )}
      <span>{title}</span>
    </button>
  );
};

export default Button;
Enter fullscreen mode Exit fullscreen mode

现在我们可以开始编写 App.jsx 了。我把样式分享给大家:

/* @src/App.module.css */

.container {
  display: flex;
  justify-content: center;
  align-items: center;
  height: 100vh;
}

.section {
  display: flex;
  justify-content: space-around;
  align-items: center;
  width: 600px;
}
Enter fullscreen mode Exit fullscreen mode

现在让我们假设这是你的组件:

// @src/App.jsx

import React, { useCallback } from "react";
import { HiOutlineSpeakerphone } from "react-icons/hi";
import { BiRightArrowAlt } from "react-icons/bi";

import styles from "./App.module.css";
import Button from "./components/Button";

const App = () => {
  const fn = useCallback((message) => {
    console.log(message);
  }, []);

  return (
    <div className={styles.container}>
      <div className={styles.section}>
        // ...
      </div>
    </div>
  );
};

export default App;
Enter fullscreen mode Exit fullscreen mode

如你所见,我们已经选择了图标,并且已经导入了 Button 组件。剩下的就是创建文章开头定义的三个按钮。

// @src/App.jsx

import React, { useCallback } from "react";
import { HiOutlineSpeakerphone } from "react-icons/hi";
import { BiRightArrowAlt } from "react-icons/bi";

import styles from "./App.module.css";
import Button from "./components/Button";

const App = () => {
  const fn = useCallback((message) => {
    console.log(message);
  }, []);

  return (
    <div className={styles.container}>
      <div className={styles.section}>
        <Button
          icon={<HiOutlineSpeakerphone />}
          title="Let us know"
          onClick={() => fn("Clicked 'Let us know' button")}
        />
        <Button
          title="Get Started"
          onClick={() => fn("Clicked 'Get Started' button")}
          primary
        />
        <Button
          icon={<BiRightArrowAlt />}
          title="Learn more"
          onClick={() => fn("Clicked 'Learn more' button")}
          hasIconRight
        />
      </div>
    </div>
  );
};

export default App;
Enter fullscreen mode Exit fullscreen mode

您应该得到类似这样的结果:

最终结果

结论

一如既往,希望你觉得这篇文章有趣。如果你发现本文有任何错误,请在评论区指出。🧑🏻‍💻

祝你度过美好的一天!🔫

文章来源:https://dev.to/franciscomendes10866/how-to-pass-components-as-props-in-react-26ig
PREV
我在学习 Web 前端开发和 Web 服务器配置时遇到的有用的网站和应用程序
NEXT
如何使用 React 和 Tailwind 创建现代卡片 让我们来编码