有条件地 return ForwardRefExoticComponent 和 FunctionalComponent

Conditionally return ForwardRefExoticComponent and FunctionalComponent

我在 MUI TextField 组件上创建了一个包装器,即 TextFieldWrapper 具有自定义样式和验证。它在许多地方都在应用程序中。

问题是它不能与 MUI Tooltip 一起使用,因为 ref 需要转发。

我不能用 React.forwardRef() 包裹 TextFieldWrapper 因为用 forwardRef 包裹它会改变它的 return 类型并且它会在其他地方中断。

所以,目前,我有 2 个 TextField 组件,即 TextFieldWrapperTooltipTextField

问题是,正如我之前所说,TextField 应用了一些样式和验证,并且在 TextFieldWrapperTooltipTextField 如果我使用如下所示的单独组件。

是否有解决此问题的方法或可以通过某种方式改进?我的意思是,如果我可以将这 2 个(TextFieldWrapperTooltipTextField)组合成一个功能组件并且 return 它有条件地或以某种方式?

代码沙盒:https://codesandbox.io/s/basictooltip-material-demo-forked-v8lrb4?file=/demo.tsx:0-799

import * as React from "react";
import { Tooltip, TextField, TextFieldProps } from "@mui/material";

// Return type is React.ForwardRefExoticComponent<Pick<TextFieldProps> & React.RefAttributes<...>>
const TooltipTextField = React.forwardRef(
  (
    props: TextFieldProps,
    ref: React.RefObject<HTMLInputElement>
  ): React.ReactElement => {
    return <TextField ref={ref} {...props} />;
  }
);

// Return type is React.React.ReactElement
const TextFieldWrapper = (props: TextFieldProps): React.ReactElement => {
  return <TextField {...props} />;
};

export default function BasicTooltip() {
  return (
    <>
      <Tooltip title="Tooltip Textfield">
        <TooltipTextField value="Tooltip TextField" />
      </Tooltip>

      <TextFieldWrapper value="General TextField" />
    </>
  );
}

您可以通过三种方式进行操作。

  1. 使用断言 as 关键字并指定您拥有的组件的类型。
const TooltipTextField = React.forwardRef(
  (props: TextFieldProps, ref: React.RefObject<HTMLInputElement>) => {
    return <TextField ref={ref} {...props} />;
  }
) as React.FC<TextFieldProps>;
  1. 用另一个 MUI 组件包装组件,例如 Box。这会将目标组件更改为 Box 并且它将执行 Tooltip.
  2. 所需的操作
<Tooltip title="Tooltip Textfield">
  <Box sx={{ display: "inline-block" }}>
    <GeneralTextField value="General TextField" />
  </Box>
</Tooltip>
  1. 创建一个组合 TooltipTextField 的组件(您提到的)。
const TextFieldWithTooltip = ({ tooltipProps, ...rest }: TextFieldProps & { tooltipProps?: TooltipProps }): React.ReactElement => {
  return (
    <Tooltip {...tooltipProps} title={tooltipProps?.title || ''}>
      <TextField {...rest} />
    </Tooltip>
  );
}

请在 https://mui.com/material-ui/api/tooltip/#props

查看工具提示道具

注意,

  • 如果您为标题传递空字符串,则不会显示工具提示。
  • 您也可以使用像 disableHoverListener 这样的道具来防止显示工具提示等

我还提供了一个可能有用的 demo on Codesandbox。遵循代码中的 FIXME 个标签 ;)