概要
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 />
コンポーネントのProps
にbackgroundColor
が存在してないので問題が発生します。
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>`
...
`
このように定義したStyledProps
とButtonProps
を一緒に使うように設定して、親コンポーネントで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で開発されています。興味がある方はアプリをダウンロードしてアプリを使ってくれると本当に助かります。