有条件地 return ForwardRefExoticComponent 和 FunctionalComponent
Conditionally return ForwardRefExoticComponent and FunctionalComponent
我在 MUI TextField 组件上创建了一个包装器,即 TextFieldWrapper
具有自定义样式和验证。它在许多地方都在应用程序中。
问题是它不能与 MUI Tooltip
一起使用,因为 ref
需要转发。
我不能用 React.forwardRef()
包裹 TextFieldWrapper
因为用 forwardRef
包裹它会改变它的 return 类型并且它会在其他地方中断。
所以,目前,我有 2 个 TextField
组件,即 TextFieldWrapper
和 TooltipTextField
。
问题是,正如我之前所说,TextField
应用了一些样式和验证,并且在 TextFieldWrapper
和 TooltipTextField
如果我使用如下所示的单独组件。
是否有解决此问题的方法或可以通过某种方式改进?我的意思是,如果我可以将这 2 个(TextFieldWrapper
和 TooltipTextField
)组合成一个功能组件并且 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" />
</>
);
}
您可以通过三种方式进行操作。
- 使用断言
as
关键字并指定您拥有的组件的类型。
const TooltipTextField = React.forwardRef(
(props: TextFieldProps, ref: React.RefObject<HTMLInputElement>) => {
return <TextField ref={ref} {...props} />;
}
) as React.FC<TextFieldProps>;
- 用另一个 MUI 组件包装组件,例如
Box
。这会将目标组件更改为 Box
并且它将执行 Tooltip
. 所需的操作
<Tooltip title="Tooltip Textfield">
<Box sx={{ display: "inline-block" }}>
<GeneralTextField value="General TextField" />
</Box>
</Tooltip>
- 创建一个组合
Tooltip
和 TextField
的组件(您提到的)。
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
个标签 ;)
我在 MUI TextField 组件上创建了一个包装器,即 TextFieldWrapper
具有自定义样式和验证。它在许多地方都在应用程序中。
问题是它不能与 MUI Tooltip
一起使用,因为 ref
需要转发。
我不能用 React.forwardRef()
包裹 TextFieldWrapper
因为用 forwardRef
包裹它会改变它的 return 类型并且它会在其他地方中断。
所以,目前,我有 2 个 TextField
组件,即 TextFieldWrapper
和 TooltipTextField
。
问题是,正如我之前所说,TextField
应用了一些样式和验证,并且在 TextFieldWrapper
和 TooltipTextField
如果我使用如下所示的单独组件。
是否有解决此问题的方法或可以通过某种方式改进?我的意思是,如果我可以将这 2 个(TextFieldWrapper
和 TooltipTextField
)组合成一个功能组件并且 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" />
</>
);
}
您可以通过三种方式进行操作。
- 使用断言
as
关键字并指定您拥有的组件的类型。
const TooltipTextField = React.forwardRef(
(props: TextFieldProps, ref: React.RefObject<HTMLInputElement>) => {
return <TextField ref={ref} {...props} />;
}
) as React.FC<TextFieldProps>;
- 用另一个 MUI 组件包装组件,例如
Box
。这会将目标组件更改为Box
并且它将执行Tooltip
. 所需的操作
<Tooltip title="Tooltip Textfield">
<Box sx={{ display: "inline-block" }}>
<GeneralTextField value="General TextField" />
</Box>
</Tooltip>
- 创建一个组合
Tooltip
和TextField
的组件(您提到的)。
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
个标签 ;)