概要
画像がリンク切れの時に表示されるimgコンポーネントってイケてないですよね。
そんな時、画像リンク切れの時は別の画像を表示したいニーズが存在すると思います。
React x Typescriptの組み合わせで微妙にハマってしまったので、整理します。
※なお、リンク切れ時には、例えば以下のように表示されます。
環境
$ node -v
v16.13.1
$ npm -v
8.1.2
実装
ポイントは、currentTarget使用する or onErrorの返り値をany型で明示的に指定してあげることでした。
※@YutaUraさんのコメントより、対策法を追加しました!ありがとうございます!
export const App: React.FC = () => {
const imgPath = 'https://pbs.twimg.com/profile_banners/1353986308062908417/1620745196/1080x360'
const dummy_img = 'https://pbs.twimg.com/profile_banners/2968069742/1628067771/1500x500'
return (
<div className="App">
<img src={imgPath} alt='sample_img' width='100%' height='auto' onError={(e) => { e.currentTarget.src = dummy_img }} />
{/* もしくは以下のように記載 */}
<img src={imgPath} alt='sample_img' width='100%' height='auto' onError={(e: any) => { e.target.src = dummy_img }} />
</div>
)
}
解説
Reactのimgコンポーネントは、React.DetailedHTMLProps<React.ImgHTMLAttributes<HTMLImageElement>, HTMLImageElement>
であり、そのonError
オプションで返却される値の型は、React.SyntheticEvent<HTMLImageElement, Event>
です。
この記事を参考に実装してみましたが、どうやらこの型にはsrcは含まれておらず、下記のようなエラーが表示されました。
{/* こうやって書くのはダメだよ */}
<img src={imgPath} alt='sample_img' width='100%' height='auto' onError={(e) => {e.target.src}}/>
Property 'src' does not exist on type 'EventTarget'.
色々試行錯誤した結果、上記のサンプルのように、currentTargetを使用するか、返り値eにany型を付けて実装することで、本エラーを回避できます。
余談
Typescriptなのにany使うとは何事だ!と怒られてしまうかもしれません。。。
いいアイデアあれば、コメントいただけると幸いです。