You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用MUI和React Hook Form创建可复用的受控TextField组件?

基于MUI和react-hook-form的可复用TextField组件实现

我正在使用React的Material UI(MUI)和react-hook-form开发表单,需要实现一个具备以下特性的可复用TextField组件:

  • 借助Controller与react-hook-form配合使用
  • 支持多种输入类型(包含带显示/隐藏功能的密码框)
  • 允许添加输入框前后的可选图标装饰
  • 可通过readOnly、variant、outerLabel等props进行自定义配置

以下是已实现的组件代码:

import {
  FormLabel,
  IconButton,
  InputAdornment,
  Stack,
  TextField,
} from "@mui/material";

// 表单相关依赖
import { Controller, useFormContext } from "react-hook-form";
import { useState } from "react";
import Visibility from "@mui/icons-material/Visibility";
import VisibilityOff from "@mui/icons-material/VisibilityOff";
import { JSX } from "@emotion/react/jsx-dev-runtime";

// ----------------------------------------------------------------------

export function RHFTextField({
  name,
  type = "text",
  variant = "outlined",
  readOnly = false,
  StartIcon,
  EndIcon,
  outerLabel,
  fullWidth = true,
  ...other
}: any): JSX.Element {
  const { control } = useFormContext();
  const [showPassword, setShowPassword] = useState<boolean>(false);

  const endAdornment =
    type === "password" ? (
      <InputAdornment position="end">
        <IconButton
          aria-label="切换密码可见性"
          onClick={() => {
            setShowPassword((prev) => !prev);
          }}
        >
          {showPassword ? <Visibility /> : <VisibilityOff />}
        </IconButton>
      </InputAdornment>
    ) : (
      EndIcon
    );

  return (
    <Controller
      name={name}
      control={control}
      render={({ field, fieldState: { error } }) => (
        <Stack gap="0.6rem">
          {outerLabel && <FormLabel>{outerLabel}</FormLabel>}
          <TextField
            {...field}
            error={Boolean(error)}
            helperText={error?.message}
            type={showPassword ? "text" : type}
            variant={variant}
            InputProps={{
              readOnly,
              endAdornment,
              startAdornment: StartIcon,
            }}
            fullWidth={fullWidth}
            {...other}
          />
        </Stack>
      )}
    />
  );
}

关键实现细节

  • 通过useFormContext获取表单上下文,配合Controller完成与react-hook-form的状态绑定
  • 针对密码类型输入框,内置了显示/隐藏切换逻辑,用useState维护密码可见状态
  • 支持通过StartIcon和EndIcon自定义输入框前后的装饰图标,密码类型会自动替换为切换图标
  • 提供outerLabel属性实现独立于输入框的外部标签,同时保留MUI TextField自身的标签配置能力
  • 支持通过variant、readOnly等props直接配置TextField的样式和状态,剩余props通过...other透传给底层组件

内容的提问来源于stack exchange,提问作者Noman Jutt

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.13 11:08:28