使用 React Hooks 构建可重用的 UI 组件
作者:Peter Ekene Eze ✏️
在 React 中,可复用组件是指可以在应用程序的不同部分使用的 UI 组件,用于构建多个 UI 实例。例如,我们可以让同一个按钮组件在应用程序的不同部分显示不同的颜色。虽然它本质上仍然是同一个按钮组件,但当我们为其提供数据集(例如颜色或函数)时,它会修改自身并输出该元素的不同 UI 实例。
这种创建 React 组件的模式对于扩展性至关重要。它有助于节省时间,因为它可以减少代码编写量,加快开发速度,简化代码库,并减轻维护压力。
在本教程中,我们将构建可复用的 React 组件,这些组件可以在整个项目中使用,以保持逻辑和表现形式的一致性。我们将使用 Hooks 来管理和操作状态数据。
本文假设您已具备 React 的基本知识。如果您没有任何 React 使用经验,可以参考此处的文档入门。本项目中使用的所有示例都可以在此沙箱中找到。
入门
在本教程的这一部分,我们将创建各种 HTML 元素作为可重用组件。我们将使用 CodeSandbox。您可以点击此处创建一个新的沙箱来开始学习。
输入组件
创建可复用的输入组件的一个优势在于,您可以保持输入框在应用程序各个部分的外观一致。您还可以通过传递 prop 来指定要渲染的输入组件类型(文本、电子邮件等)。虽然本教程不会深入探讨样式,但您可以根据自己的视觉需求自定义组件。
在新建的沙盒项目中,创建一个名为 components 的文件夹,并在FormInput.js其中创建一个文件,然后将以下代码添加到该文件中:
// ./components/FormInput.js
import React, {useState} from "react";
function FormInput(props) {
const [inputType] = useState(props.type)
const [inputValue, setInputValue] = useState('')
function handleChange(event){
setInputValue(event.target.value);
if(props.onChange) props.onChange(inputValue)
}
return (
<>
<input type={inputType} value={inputValue} name="input-form" onChange={handleChange} class="inputclass"/>
</>
);
}
export default TextInput;
为了使组件可复用,它必须接收数据或数据集(通过 props 传递),并返回输出(通常是通过 props 传递的函数)。建议将可变状态保存在组件的 state 属性中,以确保其正常工作。
上面的组件FormInput()接收一个输入类型参数,以确定要渲染的输入元素类型(例如电子邮件、文本等)。它还接收一个方法onChange()来接收从输入框返回的值。
该组件在本地管理其值,并且只将更新后的状态值返回给调用它的组件。
为了实现这一点,我们创建了一个本地函数handleChange()。该函数会检查是否可以通过 props 找到接收状态数据的方法,然后将当前状态数据发送给该方法进行进一步处理。
自定义选择组件
在您的组件文件夹中,创建一个CustomSelect.js文件并将以下代码添加到其中:
// ./components/CustomSelect.js
import React, { useState } from "react";
function CustomSelect(props) {
const [data] = useState(props.data);
const [selectedData, updateSelectedData] = useState("");
function handleChange(event) {
updateSelectedData(event.target.value);
if (props.onSelectChange) props.onSelectChange(selectedData);
}
let options = data.map(data => (
<option key={data.id} value={data.id}>
{data.name}
</option>
));
return (
<select
name="customSearch"
className="custom-search-select"
onChange={handleChange}
>
<option>Select Item</option>
{options}
</select>
);
}
export default CustomSelect;
上面,我们通过 props 接收 select 元素中 options 标签所需的数据集。为了构建 option 标签,我们遍历 props 传递的数据集,在将其渲染为 select 标签的一部分之前对其进行构建。
标签的状态(当前选定的选项)存储在本地,当其发生变化时,通过我们的本地函数进行更新并作为输出发送回去handleChange()。
按钮组件
您可以使用可复用的按钮在应用程序中显示不同的颜色或尺寸。在组件文件夹中,创建一个Button.js文件并将以下代码添加到其中:
// ./components/Button.js
import React, { useState } from "react";
function Button(props) {
const [size] = useState(props.size);
const [variant] = useState(props.variant);
return (
<button className={`btn-${variant} btn-${size}`}>{props.children}</button>
);
}
export default Button;
我们的按钮通过 props 接收三个属性:variant(用于确定按钮颜色)、size(lg、xs、sm,用于确定按钮大小)以及使用 React 内置的 children 属性(props.children)动态显示按钮内容。
模态组件
模态组件适用于在应用程序中发送提示信息。在组件文件夹中,创建一个Modal.js文件并将以下代码添加到其中:
// ./components/Modal.js
import React, { useState, useEffect } from "react";
function Modal(props) {
const [message] = useState(props.message);
const [show, setShow] = useState(props.show);
useEffect(() => {
setTimeout(() => {
setShow(false);
}, 3000);
});
return (
<div className={show ? "modal display-block" : "modal display-none"}>
<section className="modal-main">{message}</section>
</div>
);
}
export default Modal;
我们的模态组件执行两项操作:
- 它接收一个布尔值,该值决定它是否弹出。
- 它还会接收弹出窗口时要显示的消息。
要关闭模态框,我们需要将显示状态设置为 false。我们可以通过setTimeout()在useEffect()钩子函数中调用一个函数,在几秒钟后执行此操作来实现。
切换组件
切换组件用于需要回答“是”或“否”的情况。它是表单中必不可少的组件。
在您的组件文件夹中,创建一个ToggleSwitch.js文件并将以下代码添加到其中:
// ./components/ToggleSwitch.js
import React, { useState } from "react";
function ToggleSwitch(props) {
const [checked, setChecked] = useState(props.defaultChecked);
const [Text] = useState(props.Text);
function onChange(e) {
setChecked(e.target.value);
if (props.onToggleChange) props.onToggleChange(checked);
}
return (
<div className={"toggle toggle-switch"}>
<input
type="checkbox"
name={props.Name}
className="toggle-switch-checkbox"
id={props.id}
defaultChecked={checked}
onChange={onChange}
/>
{props.id ? (
<label className="toggle-switch-label" htmlFor={props.id}>
<span
className={
props.disabled
? "toggle-switch-inner toggle-switch-disabled"
: "toggle-switch-inner"
}
data-yes={Text[0]}
data-no={Text[1]}
/>
<span
className={
props.disabled
? "toggle-switch-switch toggle-switch-disabled"
: "toggle-switch-switch"
}
/>
</label>
) : null}
</div>
);
}
export default ToggleSwitch;
我们的切换组件接收以下属性:
- ID(必填):这是要传递给复选框输入控件的 ID。如果没有此 ID,组件将不会渲染。
- 文本(必填):切换开关包含一个包含两个值的数组,分别表示“真”和“假”的文本。
- 名称(可选):这将是复选框输入框的标签文本
- onChange(可选):用于接收组件返回的数据
- 已检查(可选):此参数将直接传递给元素以获取其当前状态
- 禁用(可选):这将用于设置按钮的状态
当状态发生变化时,我们会更新状态并将值发送给父组件通过 props 发送的事件监听器。
使用组件
要使用我们刚刚创建的组件,我们需要从父组件渲染它们,并将相关数据传递给它们。请将以下内容添加到您的代码中index.js:
// ./index.js
import React, { useState } from "react";
import ReactDOM from "react-dom";
import FormInput from "../components/FormInput.js";
import CustomSelect from "../components/CustomSelect.js";
import ToggleSwitch from "../components/ToggleSwitch.js";
import Button from "../components/Button.js";
import Modal from "../components/Modal.js";
import "./styles.css";
function App() {
const data = [
{
id: "1",
name: "One"
},
{
id: "2",
name: "Two"
},
{
id: "3",
name: "Three"
},
{
id: "4",
name: "Four"
}
];
function handleChange(event) {
console.log(event.target.value);
}
function onSelectChange(event) {
console.log(event.target.value);
}
function onToggleChange(event) {
console.log(event.target.checked);
}
return (
<div className="App">
<form>
<Modal show={true} message={"Hello"}>
<p>THIS IS A MODAL</p>
</Modal>
<FormInput type={"text"} onChange={handleChange} />
<FormInput type={"email"} onChange={handleChange} />
<div>
<CustomSelect data={data} onSelectChange={onSelectChange} />
</div>
<div>
<ToggleSwitch
id="id"
defaultChecked={false}
disabled={false}
Text={["Yes", "No"]}
onToggleChange={onToggleChange}
/>
</div>
<Button variant="danger" size={"sm"} >Small Button</Button>
<Button variant="primary" size={"lg"} >Smaller Button</Button>
<Button variant="warning" size={"xs"} >Big Button</Button>
</form>
</div>
);
}
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
你应该看到以下内容:
结论
在本教程中,我们学习了如何创建可复用的 React 组件。这些知识可以应用于创建高度可扩展且一致的 React 应用程序。我们还使用了 Hooks 来管理和操作状态数据。您可以在此CodeSandbox 项目中找到本文中使用的所有代码示例。
要了解有关 Hooks 和 React 组件的更多信息,请查看此处的文档。
编者按:发现本文有误?您可以在这里找到正确版本。
插件:LogRocket,一款用于 Web 应用的 DVR

LogRocket是一款前端日志工具,可让您重现问题,如同在您自己的浏览器中发生一样。无需猜测错误原因,也无需用户提供屏幕截图和日志转储,LogRocket 即可让您重现会话,快速了解问题所在。它与任何框架的应用程序完美兼容,并提供插件来记录来自 Redux、Vuex 和 @ngrx/store 的额外上下文信息。
除了记录 Redux 操作和状态之外,LogRocket 还会记录控制台日志、JavaScript 错误、堆栈跟踪、包含标头和正文的网络请求/响应、浏览器元数据以及自定义日志。它还会对 DOM 进行插桩,记录页面上的 HTML 和 CSS,即使是最复杂的单页应用程序,也能生成像素级精确的视频。
免费试用。
这篇文章《使用 React Hooks 构建可重用的 UI 组件》最初发表在LogRocket 博客上。
文章来源:https://dev.to/bnevilleoneill/building-reusable-ui-components-with-react-hooks-2e3f





