はじめに
MUIのIconButtonPropsをtypeとして、かつforwardRefを用いた際に以下のエラーメッセージがコンソール上に表示された。
Warning: Function components cannot be given refs. Attempts to access this ref will fail. Did you mean to use React.forwardRef()?
エラーメッセージが表示された時のコード
import type { IconButtonProps } from "@mui/material";
import { IconButton } from "@mui/material";
import { memo } from "react";
export const GoogleIconButton = memo<IconButtonProps>(({ children, ...props }) => {
return <IconButton {...props}>{children}</IconButton>;
});
やりたいこと
前項のコードにおけるエラーメッセージを解消する。
やったこと
色々と調べると『ref属性にuseRefの変数をpropsとして渡そうとする』と最初に記載したエラーメッセージが表示される様子。
(参考サイト:https://devsakaso.com/react-forwardref/)
確かに、前々項のコードは汎用コンポーネントで、使用していた一部の親コンポーネントにref属性を扱っているものがあった。
そのため、親コンポーネントから子コンポーネント(関数コンポーネント)のref属性を使用できるようにするため、以下のコードのようにforwardRef
を使用した。
(参考サイト:https://nishinatoshiharu.com/overview-react-ref/)
import type { IconButtonProps } from "@mui/material";
import { IconButton } from "@mui/material";
import { forwardRef, memo } from "react";
export const GoogleIconButton = memo(forwardRef<IconButtonProps>(({ children, ...props }) => {
return <IconButton {...props}>{children}</IconButton>;
}));
すると、以下の別のエラーメッセージが表示された。
Component is not optimized. Please add a shouldComponentUpdate method.
これは簡単に言うと『コンポーネント中でpropsの各プロパティを使おうとするとESLintによってエラー扱いになる』ということだそう。
なので定義を分割してコードを再構築した。
(参考サイト:https://qiita.com/ckbys/items/7a7904a95289b7160c93)
import type { IconButtonProps } from "@mui/material";
import { IconButton } from "@mui/material";
import { forwardRef, memo } from "react";
const GoogleIconButtonDefinition = forwardRef<IconButtonProps>(({ children, ...props }) => {
return <IconButton {...props}>{children}</IconButton>;
});
export const GoogleIconButton = memo(GoogleIconButtonDefinition);
ここでまた別のエラーメッセージが表示された。
プロパティ 'children' は型 '{}' に存在しません。
forwardRef<IconButtonProps>
という形だと認識されないようだったので、原因など色々調べた結果、次項のコードに落ち着いた。
(参考サイト:https://zenn.dev/doke/articles/880f03c35576b5)
回避策(コード内容)
import type { IconButtonProps } from "@mui/material";
import { IconButton } from "@mui/material";
import { forwardRef, memo } from "react";
const GoogleIconButtonDefinition = forwardRef(({ children, ref, ...props }: IconButtonProps) => {
return (
<IconButton ref={ref} {...props}>
{children}
</IconButton>
);
});
export const GoogleIconButton = memo(GoogleIconButtonDefinition);
これで最初のエラーメッセージは解消された。