繁体   English   中英

为什么自定义输入组件会导致“Function components cannot be given refs”警告?

[英]Why does custom input component cause "Function components cannot be given refs" warning?

在尝试通过MUI 的InputUnstyled组件(或任何其他无样式组件,例如SwitchUnstyledSelectUnstyled等)自定义input组件时,我收到警告

Warning: Function components cannot be given refs. Attempts to access this ref will fail. Did you mean to use React.forwardRef()?

Check the render method of `ForwardRef`.
InputElement@http://localhost:3000/main.4c2d885b9953394bb5ec.hot-update.js:59:45
div
...

我使用components属性在我自己的MyStyledInput组件中定义了一个自定义Input元素,该组件包装了 MUI InputUnstyled

import InputUnstyled, {
    InputUnstyledProps
} from '@mui/base/InputUnstyled';

const MyStyledInput: React.FC<InputUnstyledProps> = props => {
    const { components, ...otherProps } = props;

    return (
        <InputUnstyled
            components={{
                Input: InputElement,
                ...components,
            }}
            {...otherProps}
        />
    );
};

我的自定义input组件InputElement导致Function components cannot be given refs警告:

import {
    InputUnstyledInputSlotProps,
} from '@mui/base/InputUnstyled';
import { Box, BoxProps } from '@mui/material';

const InputElement: React.FC<BoxProps & InputUnstyledInputSlotProps> = (
    { ownerState, ...props }
) => {
    return (
        <Box
            component="input"
            // any style customizations
            {...props}
            ref={ref}
        />
    );
});

注意:我正在使用component="input使 MUI 的Box组件不呈现 HTML div而是呈现 DOM 中的 HTML input组件。

为什么我会收到此警告?

此处此处此处的其他相关问题解决了类似问题,但不适用于 MUI Unstyled 组件。 这些线程也没有解释为什么

该警告希望您查看InputElement组件。 老实说,堆栈跟踪在这里有点误导。 它说:

检查ForwardRef的渲染方法。 InputElement@http://localhost:3000/main.4c2d885b9953394bb5ec.hot-update.js:59:45 div

您可以在此处忽略ForwardRef 内部InputElement

理解此警告的关键部分是:

Function 组件不能给出参考。 尝试访问此 ref 将失败。

也就是说,如果有人试图通过ref访问 DOM 中实际的 HTML input元素(Material UI 实际上试图这样做),它将不会成功,因为功能组件InputElement无法将该ref传递给input元素(此处通过 MUI Box组件创建)。

因此,警告继续:

你的意思是使用 React.forwardRef() 吗?

这提出了用React.forwardRef包装 function 组件的解决方案。 forwardRef使您可以获取ref并将其传递给实际的input组件(在本例中是带有 prop component="input"Box组件)。 它应该看起来像这样:

import {
    InputUnstyledInputSlotProps,
} from '@mui/base/InputUnstyled';
import { Box, BoxProps } from '@mui/material';

const InputElement = React.forwardRef<
    HTMLInputElement,
    BoxProps & InputUnstyledInputSlotProps
>(({ ownerState, ...props }, ref) => {
    const theme = useTheme();

    return (
        <Box
            component="input"
            // any style customizations
            {...props}
            ref={ref}
        />
    );
});

为什么我必须首先处理ref

对于 HTML input元素,您很可能希望通过ref访问它的 DOM 节点。 如果您将 React input组件用作不受控制的组件,就会出现这种情况。 不受控制的输入组件将其 state(即用户在该输入字段中输入的任何内容)保存在实际的 DOM 节点中,而不是在React.useState挂钩的 state 值内部。 如果您通过React.useState挂钩控制输入值,则您将输入用作受控组件

注意type="file"的输入始终是不受控制的组件。 这在关于文件输入标签的 React 文档部分中进行了解释。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM