- この記事はReact #2 Advent Calendar 2019の16日目の記事です(体調崩していたため遅くなってしまいました。すみません。。)
概要
- Slackなどでよく見かけるこのような絵文字は皆さんご存知かと思います

- これを自分の開発するReactアプリに取り入れたくて調べてみたところEmoji Martというライブラリがありました
- 日本語で使い方を説明する記事がほとんどなかったので紹介したいと思います
- ちなみにEmoji Mart以外だとemoji-picker-reactというのもあって、Qiitaの絵文字はコードを見た感じこちらが使われているようです
セットアップ
- npmのライブラリとして公開されているので
npm install
でインストールします
npm i emoji-mart
# or
yarn add emoji-mart
- これで準備OK
コンポーネント
- Emoji Martでは
<Picker />
と<Emoji />
の2つのコンポーネントが提供されています - Pickerは絵文字を選択するUIを表示するコンポーネントです

- Emojiは個々の絵文字を表示するコンポーネントです

- それぞれもう少し詳細まで見てみます
Picker
import { Picker } from 'emoji-mart';
import 'emoji-mart/css/emoji-mart.css';
- 使う際はcssとセットでimportします
- 公式のREADMEを見るとPickerコンポーネントは30ほどのpropsを受け付けます
- 細かい所の調整がいろいろできるだけなので重要どころだけピックアップします
onSelect
<Picker onSelect={emoji => alert(JSON.stringify(emoji))} />

-
onSelect
は絵文字を選択したときに呼ばれる関数です - 引数で選択した絵文字の情報を受け取れます(上記キャプチャ参照)
-
id
の値をサーバへ送信することになるでしょう
set/native
<Picker onSelect={emoji => alert(JSON.stringify(emoji))} set="google" />
- 絵文字の種類を変えることができます
-
set
には'apple', 'google', 'twitter', 'emojione', 'messenger', 'facebook'のいずれかを設定することができます(defaultはapple) - それぞれの見た目の違いは公式のサンプルでチェックできます

<Picker onSelect={emoji => alert(JSON.stringify(emoji))} native />
-
native
を渡すとset
の値は無視されunicodeの絵文字が使用されます -
set
で指定する絵文字は画像を使っていて通信処理が発生するためnative
の方が表示速度は早くなります

i18n
<Picker
i18n={{
search: '検索',
categories: {
search: '検索結果',
recent: 'よく使う絵文字',
people: '顔 & 人',
nature: '動物 & 自然',
foods: '食べ物 & 飲み物',
activity: 'アクティビティ',
places: '旅行 & 場所',
objects: 'オブジェクト',
symbols: '記号',
flags: '旗',
custom: 'カスタム',
},
}}
/>

- 絵文字のカテゴリなどを日本語化できます
Emoji
import { Emoji } from 'emoji-mart';
- 公式のREADMEを見るとEmojiコンポーネントの方は13のpropsを受け付けます
- ぱっと見て用途が想像つきやすいものばかりなのでそれほどややこしくないです
emoji/size
<Emoji emoji="thinking_face" size={64} />

-
emoji
とsize
の2つが必須項目です -
emoji
はPicker
のonSelect
のところで登場したid
に当たる値を入れればOKです -
size
は単純に大きさを指定します
onClick
<Emoji emoji="thinking_face" size={64} onClick={emoji => alert(JSON.stringify(emoji))} />

- 絵文字をクリックしたときに呼ばれる関数です
-
Picker
のonSelect
と同じ用に絵文字の情報を取得できます - 誰かが押した絵文字をクリックすると自分も押したことになる、なんて挙動をするアプリがよくありますよね
- そんな実装をするときに便利そうです
set/native
- こちらは
Picker
での説明と全く同様です
サンプル
- 簡単ではありますが動くコードも載せておきます
- create-react-appしてApp.jsをこれに書き換えたら動くはずです
- https://react-emoji-sample.netlify.com/
App.js
import React, { useState } from 'react';
import { Emoji, Picker } from 'emoji-mart';
import 'emoji-mart/css/emoji-mart.css';
const emojiTypeList = [
'apple',
'google',
'twitter',
'emojione',
'messenger',
'facebook',
];
function App() {
const [emojiList, setEmojiList] = useState([]);
const [emojiType, setEmojiType] = useState(null);
const onClickButton = e => {
setEmojiType(e.target.name);
};
const onSelect = emoji => {
console.log({ emoji });
setEmojiList([...emojiList, emoji]);
setEmojiType(null);
};
return (
<>
<p>
{emojiTypeList.map(name => (
<button onClick={onClickButton} name={name} key={name}>
{name}
</button>
))}
</p>
{emojiType && (
<Picker
onSelect={emoji => onSelect({ ...emoji, emojiType })}
set={emojiType}
i18n={{
search: '検索',
categories: {
search: '検索結果',
recent: 'よく使う絵文字',
people: '顔 & 人',
nature: '動物 & 自然',
foods: '食べ物 & 飲み物',
activity: 'アクティビティ',
places: '旅行 & 場所',
objects: 'オブジェクト',
symbols: '記号',
flags: '旗',
custom: 'カスタム',
},
}}
style={{
position: 'absolute',
zIndex: '1',
}}
/>
)}
{emojiList.length
? emojiList.map(({ id, emojiType }, i) => (
<Emoji
emoji={id}
size={32}
set={emojiType}
onClick={emoji => onSelect({ ...emoji, emojiType })}
key={i}
/>
))
: null}
</>
);
}
export default App;
まとめ
- Emoji Martを使うとそれほど苦労することなくSlack風絵文字をアプリに入れることができました
- READMEを最初に見たときはpropsの多さに身構えてしまいましたが、ちゃんとドキュメントを読んで手を動かせば理解することができました