概要
React.jsでホームページを作っている時にHTMLのエスケープでハマってしまったのでメモします。
実装
具体的に、以下のようなテーブルを作る例で示します。
この時、初心者の皆さんはmapを使って以下のように記述すると思います。
.jsx
import React from 'react';
const App = () => {
const messages = [
{ title: '名称', mes: 'AAA株式会社' },
{ title: 'URL', mes: 'http://aaa.com' },
{ title: '資本金', mes: 'AAA万円' },
{ title: 'メンバー', mes: 'AAA <br/> BBB <br/> CCC <br/> DDD </br> EEE' },
];
const messageLists = messages.map((e, index) => (
<tr key={index + 1}>
<td>{e.title}</td>
<td> {e.mes } </td>
</tr>
));
return (
<table>
<th>title</th>
<th>メッセージ</th>
{ messageLists }
</table>
);
};
export default App;
しかし、JSXの中で生のHTMLを書くと、以下のように<br/>
が文字列として認識されてしまいます。
そこで、しっかりと<br/>
を改行と認識させるためにはdangerouslySetInnerHTMLを用いて以下のように記述します。
.jsx
import React from 'react';
const App = () => {
const messages = [
{ title: '名称', mes: 'AAA株式会社' },
{ title: 'URL', mes: 'http://aaa.com' },
{ title: '資本金', mes: 'AAA万円' },
{ title: 'メンバー', mes: 'AAA <br/> BBB <br/> CCC <br/> DDD </br> EEE' },
];
const messageLists = messages.map((e, index) => (
<tr key={index}>
<td>{e.title}</td>
<td dangerouslySetInnerHTML={{__html: e.mes}} />
</tr>
));
return (
<table>
<th>タイトル</th>
<th>メッセージ</th>
{ messageLists }
</table>
);
};
export default App;
すると、以下のようにうまく表示されます。
大成功ですね。
最後に
dangerouslySetInnerHTMLにはXSSの脆弱性があるのでむやみやたらに使用するのは避けましょう。