[Emotion] React does not recognize the XXXXX prop on a DOM element 問題解決方法

2022-10-22 hit count image

Emotionを使う時、発生する React does not recognize the XXXXX prop on a DOM element 問題を解決する方法について説明します。

概要

ReactプロジェクトでEmotionで開発する時、時々次のようなエラーが発生します。

console.error
  Warning: React does not recognize the `backgroundColor` prop on a DOM element. If you intentionally want it to appear in the DOM as a custom attribute, spell it as lowercase `backgroundcolor` instead. If you accidentally passed it from a parent component, remove it from the DOM element.
      at button
      ...

今回のブログポストではこのエラーがなぜ発生するか、この問題をどう解決するのかについて説明します。

React does not recognize the XXXXX prop on a DOM element エラーが発生する理由

私たちはReactプロジェクトでEmotionでスタイルを適用する時、次のようにスタイルを使います。

const StyledButton = styled('button')`
  background-color: red;
`

この時、Emotionで適用したスタイルを動的に変更したい場合、次のようにPropsを使うように変更します。

interface StyledProps {
  readonly backgroundColor?: string
}

const StyledButton = styled('button')<StyledProps>`
  background-color: ${({ backgroundColor }) =>
    backgroundColor != null ? backgroundColor : 'read'};
`

現在コードは基本的なHTMLタグにスタイルを適用してます。次は既に作ったコードに動的でスタイルを適用して見ると次のようです。

import { Button } from '@mui/material'

interface StyledProps {
  readonly backgroundColor?: string
}

const StyledButton = styled(Button)<StyledProps>`
  background-color: ${({ backgroundColor }) =>
    backgroundColor != null ? backgroundColor : 'read'};
`

例題コードはMUIライブラリの<Button />コンポーネントにEmotionを作った動的スタイルを適用したコードです。

このように既に作ってあるコンポーネントにスタイルを適用する場合、次のようなエラーが発生します。

console.error
  Warning: React does not recognize the `backgroundColor` prop on a DOM element. If you intentionally want it to appear in the DOM as a custom attribute, spell it as lowercase `backgroundcolor` instead. If you accidentally passed it from a parent component, remove it from the DOM element.
      at button

このエラーが発生する理由はMUIが適用する<Button />コンポーネントのPropsbackgroundColorが存在してないので問題が発生します。

Emotionは基本的親コンポーネントから受けたPropsをスタイルの対象になるコンポーネントに渡します。なので、このような問題が発生します。

shouldForwardProp

このような問題を解決するため、EmotionではshouldForwardPropオプションを提供してます。

shouldForwardPropオプションを使うと、次のように親コンポーネントから受けたProps中でスタイルの対象になるコンポーネントに渡すPropsをフィルタリングして提供することになります。

import { Button } from '@mui/material'
import type { ButtonProps } from '@mui/material'

interface StyledProps {
  readonly backgroundColor?: string
}

const StyledButton = styled(Button, {
  shouldForwardProp: (propName) => propName !== 'backgroundColor',
})<StyledProps & ButtonProps>`
  ${(props) =>
    props.backgroundColor != null
      ? `background-color: ${props.backgroundColor};`
      : ''}
`

MUIが提供する<Button />コンポーネントは基本的にButtonPropsを持っています。ここで私たちが使いたいスタイルをStyledPropsを使って定義しました。

import type { ButtonProps } from '@mui/material'

interface StyledProps {
  readonly backgroundColor?: string
}

const StyledButton = styled(Button, ...)<StyledProps & ButtonProps>`
  ...
`

このように定義したStyledPropsButtonPropsを一緒に使うように設定して、親コンポーネントでMUI<Button />コンポーネントのPropsを使えるようにして、私たちが生成したPropsデーターも指定できるようにします。

その後、次のようにshouldForwardPropオプションを使ってスタイルの対象になるコンポーネントに必要なPropsのみ渡すように変更します。

const StyledButton = styled(Button, {
  shouldForwardProp: (propName) => propName !== 'backgroundColor',
})<StyledProps & ButtonProps>`
  ...
`

そしたらstyled関数はshouldForwardPropのフィルタリングされた結果をスタイルの対象になるコンポーネントに渡すようになるので、React does not recognize the XXXXX prop on a DOM elementエラーを解決することができます。

完了

これでEmotionを使って既に存在するコンポーネントにスタイルを適用する時、発生する問題であるReact does not recognize the XXXXX prop on a DOM elementエラーがなぜ発生するのか、どうすれば直せるのかを確認しました。

私のブログが役に立ちましたか?下にコメントを残してください。それは私にとって大きな大きな力になります!

アプリ広報

今見てるブログを作成たDekuが開発したアプリを使ってみてください。
Dekuが開発したアプリはFlutterで開発されています。

興味がある方はアプリをダウンロードしてアプリを使ってくれると本当に助かります。

Posts