如何在 React 中将组件作为 Props 传递
让我们开始编码
概述
让组件可复用的方法之一是传递 props,无论它们是字符串、整数、布尔值、对象、数组等等。但最终你需要复用组件,而你唯一需要修改的就是例如 header 部分。
最常用的方式是使用children,也就是说,你会有一个父组件,它有一个开始和结束标签。如果你只需要更改一个组件,则无需执行任何其他操作,但是如果你需要传递多个组件,情况就有所不同。
为此,理想的情况是拥有一个带有自闭合标签的父组件,如果在 props 中传递了子组件,则该标签会呈现子组件。
今天的例子
今天我们要创建三个完全不同的按钮,一个左边有图标,一个没有图标,一个右边有图标。
但是,我们将重用相同的组件,并通过道具来改变图标的位置和按钮的背景颜色。
此外,您可能已经知道,图标将作为道具传递。
让我们开始编码
让我们安装以下依赖项:
npm install classnames react-icons
此应用程序中的所有组件样式都将使用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;
}
现在我们可以开始处理我们的 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;
现在让我们定义我们将在组件中接收的道具:
- 图标——将是图标组件;
- 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;
现在我们来处理图标。如果它传入了 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;
最后,只需添加标题,以便按钮具有一些文本内容,我们将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;
现在我们可以开始编写 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;
}
现在让我们假设这是你的组件:
// @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;
如你所见,我们已经选择了图标,并且已经导入了 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;
您应该得到类似这样的结果:
结论
一如既往,希望你觉得这篇文章有趣。如果你发现本文有任何错误,请在评论区指出。🧑🏻💻
祝你度过美好的一天!🔫
文章来源:https://dev.to/franciscomendes10866/how-to-pass-components-as-props-in-react-26ig