styled-componentsで`Received "true" for a non-boolean attribute`というエラーが出たときの対処法

下記のようにstyled-componentsでactivatedというプロパティがtrueのときには`font-weight: bold;`になるようなコンポーネントを作りたいとします。
※記法はjsxを採用

```jsx:WrapperComponent.jsx
import React from "react";
import styled, { css } from "styled-components";

const TextComponent = (props) => {
    return (
        <span {...props} className={props.className}>
            テキストテキストテキストテキスト
        </span>
    );
};

export const WrapperComponent  = styled(TextComponent)`
    color: #999;
    font-size: 14px;

    ${(props) =>
        props.activated &&
        css`
            color: #000;
            font-weight: bold;
        `}
`;
```

```jsx:利用元のPage.jsx
import React from "react";
import { WrapperComponent } from "./WrapperComponent";

const Page = (props) => {
    return (
        <WrapperComponent activated={true} />
    );
};
```

するとこんな警告が発生します。
![スクリーンショット 2021-03-25 20.36.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202053/052fea73-a023-b441-c085-91907b913866.png)

```:警告内容
Warning: Received `true` for a non-boolean attribute `activated`.
```

# エラー発生の理由
このエラーの発生の理由はstyled-componentsの公式FAQに記載されています。

https://styled-components.com/docs/faqs#why-am-i-getting-html-attribute-warnings

>The warning message below indicates that non-standard attributes are being attached to HTML DOM elements such as \<div> or \<a>.

>この警告メッセージは標準ではない引数がHTMLのDOMに渡されたことを示しています。

この警告が発生しても動作に影響は起きませんが、できる限り不要なエラーは潰しておきたいものです。

# エラーの対策
対策自体は簡単で、`{...props}`と受け取ったプロパティをそのまま\<span>や\<div>といった標準のHTML DOMに渡すのをやめれば警告は消えます。

```jsx:修正後
import React from "react";
import styled, { css } from "styled-components";

const TextComponent = (props) => {
    return (
        // {...props}を削除
        <span className={props.className}>
            テキストテキストテキストテキスト
        </span>
    );
};

const WrapperComponent  = styled(TextComponent)`
    color: #999;
    font-size: 14px;

    ${(props) =>
        props.activated &&
        css`
            color: #000;
            font-weight: bold;
        `}
`;
```

エラーが表示されなくなりました。
![スクリーンショット 2021-03-25 20.47.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202053/3d9b7922-323a-38a2-7177-9c845927eb05.png)


# スタイリングするコンポーネントがライブラリのコンポーネントの場合
ただし、外部のコンポーネントを使用して、この警告に遭遇した場合には同じような対処はできません。
実は自分がこのWarningにハマったのも、FontAwesomeIconという外部のコンポーネントを使用したときでした。

https://fontawesome.com/

```jsx:使用例
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";

const WrapperComponent  = styled(FontAwesomeIcon)`
    color: #999;
    font-size: 14px;

    ${(props) =>
        props.activated &&
        css`
            color: #000;
            font-weight: bold;
        `}
`;
```

この場合には、受け渡す値をboolean型からnumber型に変えることで警告が発生しなくなりますので、それで対応します。
(下記の記事参照)

https://dev.to/jeansmaug/how-to-fix-the-received-true-for-a-non-boolean-attribute-error-3pm9

```jsx:対応後のPage.jsx
import React from "react";
import { WrapperComponent } from "./WrapperComponent";

const Page = (props) => {
    return (
        // +trueで1,+falseで0と評価される
        <WrapperComponent activated={+true} />
    );
};
```

※正直これで警告が消える理由はよく分かりません。Boolean型のときのみ例の警告が出るようです。

# 補足
今回のケースに限らず自作のコンポーネントの場合には、想定しないエラーが起きないよう、関数の引数に分割代入を使用して、コンポーネント内で利用する予定のものだけを割り当てるようにするべきでしょう。

```jsx:分割代入を利用したFunctionComponentの作り方
const TextComponent = ({className}) => {
    return (
        <span className={className}>
            テキストテキストテキストテキスト
        </span>
    );
};
```