发布于 2026-01-06 1 阅读
0

使用 React Hooks 构建可重用的 UI 组件

使用 React Hooks 构建可重用的 UI 组件

作者:Peter Ekene Eze ✏️

在 React 中,可复用组件是指可以在应用程序的不同部分使用的 UI 组件,用于构建多个 UI 实例。例如,我们可以让同一个按钮组件在应用程序的不同部分显示不同的颜色。虽然它本质上仍然是同一个按钮组件,但当我们为其提供数据集(例如颜色或函数)时,它会修改自身并输出该元素的不同 UI 实例。

这种创建 React 组件的模式对于扩展性至关重要。它有助于节省时间,因为它可以减少代码编写量,加快开发速度,简化代码库,并减轻维护压力。

在本教程中,我们将构建可复用的 React 组件,这些组件可以在整个项目中使用,以保持逻辑和表现形式的一致性。我们将使用 Hooks 来管理和操作状态数据。

本文假设您已具备 React 的基本知识。如果您没有任何 React 使用经验,可以参考此处的文档入门。本项目中使用的所有示例都可以在此沙箱中找到。

LogRocket 免费试用横幅

入门

在本教程的这一部分,我们将创建各种 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;
Enter fullscreen mode Exit fullscreen mode

为了使组件可复用,它必须接收数据或数据集(通过 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;
Enter fullscreen mode Exit fullscreen mode

上面,我们通过 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;
Enter fullscreen mode Exit fullscreen mode

我们的按钮通过 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;
Enter fullscreen mode Exit fullscreen mode

我们的模态组件执行两项操作:

  • 它接收一个布尔值,该值决定它是否弹出。
  • 它还会接收弹出窗口时要显示的消息。

要关闭模态框,我们需要将显示状态设置为 false。我们可以通过setTimeout()useEffect()钩子函数中调用一个函数,在几秒钟后执行此操作来实现。

modal.js

切换组件

切换组件用于需要回答“是”或“否”的情况。它是表单中必不可少的组件。

在您的组件文件夹中,创建一个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;
Enter fullscreen mode Exit fullscreen mode

我们的切换组件接收以下属性:

  • ID(必填):这是要传递给复选框输入控件的 ID。如果没有此 ID,组件将不会渲染。
  • 文本(必填):切换开关包含一个包含两个值的数组,分别表示“真”和“假”的文本。
  • 名称(可选):这将是复选框输入框的标签文本
  • onChange(可选):用于接收组件返回的数据
  • 已检查(可选):此参数将直接传递给元素以获取其当前状态
  • 禁用(可选):这将用于设置按钮的状态

当状态发生变化时,我们会更新状态并将值发送给父组件通过 props 发送的事件监听器。

切换开关 js

使用组件

要使用我们刚刚创建的组件,我们需要从父组件渲染它们,并将相关数据传递给它们。请将以下内容添加到您的代码中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);
Enter fullscreen mode Exit fullscreen mode

你应该看到以下内容:

结论

在本教程中,我们学习了如何创建可复用的 React 组件。这些知识可以应用于创建高度可扩展且一致的 React 应用程序。我们还使用了 Hooks 来管理和操作状态数据。您可以在此CodeSandbox 项目中找到本文中使用的所有代码示例。

要了解有关 Hooks 和 React 组件的更多信息,请查看此处的文档


编者按:发现本文有误?您可以在这里找到正确版本。

插件:LogRocket,一款用于 Web 应用的 DVR

 
LogRocket 控制面板免费试用横幅
 
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