ReactJS の案件に携わってから1年近く経ったので 今までに出会ったライブラリの中で便利だったものを自作の DEMO とコード付きで紹介していきます。
CSSは頑張りません。ださくてもしょうがない。
- info
- この記事のデモとコードは2021/09のブログ引っ越しに合わせて codesandbox に変更しました。 それに合わせて一部のコードを書き換えたり、他のサンプルに(forkして)置き換えたりしてます。
- バージョンは 修正時点の最新だったり、サンプルが使っているバージョンだったりでバラバラ なのであくまで参考程度に御覧ください。
- 詳しいオプションは公式ドキュメントを参照してください。
- 間違っていたり、もっといいやり方がある場合は優しめに教えてください。
- いろいろ動作検証しながらやったので不要なコードが多少残っているかもしれませんが気にしないでください。
react-notification-system
通知用のライブラリです。
- バージョン
- 0.4.0
- リポジトリ
- サンプル
通知位置とメッセージを入力してボタンを押してください。
通知内にボタンを設定できるんですが何も思い浮かばなかったので、Twitter のリンクにしました。フォローしてね!
- info
react-pdf
PDF.js という PDF を描画できるライブラリがあり、これはReact用のラッパーです。
PDF.js を生で操作すると (たしか) pdfjs-dist/build/pdf
や
pdfjs-dist/web/pdf_viewer
の読み込みを別途行わないといけないんですが、
これはコンポーネント化されてるので細かい点を気にせず使えます。
- バージョン
- 4.1.0
- リポジトリ
- warning
- diegomura/react-pdf ではないです
- Star はこっちのほうが多いんですが、ドキュメントを読む限りでは 既存のPDFを描画する機能はなく、 そもそも用途が PDF を作るためのライブラリのようです。
- 見逃してる可能性もあるので、「できるよー」って場合は教えてください。
- サンプル
- Displaying PDF using React をベースに、自分で選択したPDFを表示できるように機能追加しました
- 参考
react-modal
- バージョン
- 3.14.3
- リポジトリ
- サンプル
- YouTube の動画をモーダル表示するようにしてみました
react-select
セレクトボックスを高機能にしたライブラリです。
- バージョン
- 2.0.0
- リポジトリ
- サンプル
- react-select sandbox をクローンしました
複数選択 の場合は isMulti
を props に指定します。
今回は指定してませんが、 className
でクラスを指定したほうがいいです。 クラスを指定しないと
css-xxxxxxx
(xxxxxxxは可変)のようなクラス名しかつかないので、内側のDOMにスタイルを当てられません。
(メニューのz-indexが負けて後ろに隠れちゃうのはよくあります)
- info
- 少し前に version 2.0.0 がリリースされました。 v2 では使い方が大きく変わり、 v1 のコードでは動かなくなってます。
- 具体的な変更点は以下です。
- 選択中は key ではなく、
{key, label}
のオブジェクトを指定するようになった - AsyncSelect は
react-select
ではなくreact-select/lib/Async
から(default)インポートするようになった - loadOptions の関数内で自分で
{key, label}
の配列に整形して返却する(必要がある)ようになった。- v1 の AsyncSelect では
filterOption
やvalueKey
,labelKey
などでレスポンスの整形を ライブラリに任せていた
- v1 の AsyncSelect では
- AsyncSelect では 入力文字列がないときにリクエストが発生しなくなった
- 選択中は key ではなく、
- こんな感じです。いろいろと統一されてわかりやすくなってると思います。
react-dropzone
ドラッグアンドドロップでファイルを添付(アップロード)するのに便利なライブラリです。
DropzoneJS というライブラリがあり、これはReact用のラッパーです。
- バージョン
- 11.4.0
- リポジトリ
- サンプル
- warning
- codesandbox の embedded だとドラッグアンドドロップの操作ができないようです。実際に動かしたい方は codesandbox に直接アクセスしてご利用ください。
- info
- JSON 形式で送信したい場合は Base64 化など工夫が必要です
多少余談も入りますが、Vue では たしか vue2-dropzone
というのがあり、
(たしか)そちらはドラッグした瞬間にファイルがアップロードされます。
Reactのほうは自分でアップロード処理も自分でやる必要があります。 その場合、ドロップされたファイル配列中の要素が File オブジェクトなので そのままアップロードしてあげればよいです。
react-autocomplete
文字通り 入力補完のライブラリです。 入力文字に対応した選択肢が表示され、選択した選択肢の内容で補完されます。
react-rnd
DOM の リサイズと 移動(ドラッグアンドドロップ) を行うためのライブラリです。
単体で リサイズや ドラッグアンドドロップを行うライブラリは他にもありましたが 組み合わせるといろいろ不具合があって困ってました。
そんな中で奇跡的に見つけました。細かい制御もできて便利です。
- バージョン
- 8.0.1
- リポジトリ
- サンプル
- xpm699v4lp sandboxをクローンしました
- info
- ただのバグかもしれませんが position props は 指定すると リサイズしたときに位置が固定されて、 左側を縮小したのに右側から縮むという直感的でない動作をするので管理していません。
- 同じ作者が出している リサイズ機能だけと思われる re-resizable というライブラリがありますが、このライブラリと比べてどのような優位性があるのかは不明です(調べてません)。
- drag and drop
だけであれば以下のライブラリも使いやすかったです。(作者は違います)
- react-rnd で済む場合はこちらのライブラリは不要だと思います。
- バージョン
- 3.1.1
- リポジトリ
- サンプル
- react-draggable sandboxをクローンしました
ちょっと説明が難しいんですが、 フリーカーソル的 な 自由移動なので、 ドラッグして順番を入れ替えるような用途では後述する react-dnd が便利です。
(もちろん頑張ればできると思いますが)
react-dnd
要素をドラッグアンドドロップ (Drag and Drop) するためのライブラリです。
前述した react-rnd と名前も用途も似ていますが、 始点と終点の制御を細かく設定できるのが特徴です。
要素のソート等にも適しています。
- バージョン
- 14.0.3
- リポジトリ
- サンプル
- warning
- codesandbox の embedded だとドラッグアンドドロップの操作ができないようです。実際に動かしたい方は codesandbox に直接アクセスしてご利用ください。
- ルールなど
- 数字を並び替えるゲームを自力で実装してみました。よくしらないですが、15ゲーム(?)というらしいです。 デフォルトだと 3x3 なので 多分 8ゲームです
- 空白のセルに退避しつつ数字を左上から順に並びかえるだけの単純なルールです
- 正しい場所に来ると 色がつきます
- ランダムで配置してます。
- PC でしか動きません。
- yahoo/react-dnd-touch-backend を使うことで スマホ対応できそうですが今回はやってません。
react-dnd は 他のライブラリに比べて少し概念的にむずかしいです。 あとコピペで動くサンプルがなかなかみつからなくて辛いです(感想)。
正直自分もちゃんとは理解できてないと思ってますが とりあえず解説します。
このライブラリは 以下の 3つの概念から成り立っています。
- Drag source
- ドラッグして動かしたい対象
- DragSource クラスで動かす対象の動きを定義し、その定義で動かす対象のコンポーネントをラップする
- 今回は beginDrag と endDrag を定義
- Drop target
- ドロップする対象の領域
- DropTarget クラスでドロップ領域の動作や制限を定義し、その定義で領域のコンポーネントをラップする
- 今回は canDrop と drop を定義
- canDrop がドロップ時の制限にあたる (true or false を返却する)
- drop が 領域情報を返却する
- Drag and Drop context
- 上記2つを仲介するコンポーネント領域
- 公式では
DragDropContextProvider
で要素をラップするような例が記述されてるんですが、 今回はDragDropContext(HTML5Backend)
で作ったラッパーでコンポーネントをラップしてます - 理由としては (この場合はサイズ変更で) 要素が増えたときに
Cannot have two HTML5 backends at the same time
というエラーが発生します。 これはHTML5Backend
というオブジェクトが同時に複数作成されることが原因のようです。 - 別の回避策としては、一度対象のDOMを消して(Unmount) してから再描画するとうまくいきます
- 今回だと
this.state.cells
を[]
にして unmount されたあとに再描画するとうまくいきます。this.setState
のコールバックで呼び出す
- info
ES7 の公式テキストでは 上記のラッパーをデコレータで適用するような例が書いてありましたが、 同じようにしたところ
props
から得られるconnect
関連のオブジェクトがうまく受け取れずエラーになってしまい、 仕方なく、一旦変数に落としてからラップしてます。やってることは同じはずなんですが原因がわかりません。優しい人は教えてください。
もし同じような要件なら以下を使ってみたい。
参考
終わりに
いかがだったでしょうか。役に立ちそうなライブラリは見つかりましたか?
他にも有用なライブラリはたくさんあると思いますが、時間の都合上今回はここまでということで。 次回があるかはわかりませんが、リクエストをいただけたらとりあげるかもしれません。