巷で難しい難しいと言われていた react-dnd が hookでかなり楽に実装できるようになっていたので、自作アプリにDnD機能を追加したところ、gatsbyのビルド時にエラーが出て止まってしまいました
試行環境
ソフトウェア | バージョン |
---|---|
MacOS | 10.15.6 |
React | 16.13.1 |
Gatsby | 2.24.2 |
React-dnd | 11.1.3 |
React-dnd-html5-backend | 11.1.3 |
エラー内容
failed Building static HTML for pages - 24.502s
ERROR #95313
Building static HTML failed for path "/dashboard/"
See our docs page for more info on this error: https://gatsby.dev/debug-html
27 | } else {
28 | var argIndex = 0;
> 29 | error = new Error(format.replace(/%s/g, function () {
| ^
30 | return args[argIndex++];
31 | }));
32 | error.name = 'Invariant Violation';
WebpackError: Invariant Violation: Expected drag drop context
- invariant.esm.js:29
node_modules/@react-dnd/invariant/dist/invariant.esm.js:29:1
- useDragDropManager.js:12
node_modules/react-dnd/dist/esm/hooks/useDragDropManager.js:12:12
- drag.js:23
node_modules/react-dnd/dist/esm/hooks/internal/drag.js:23:35
- useDrag.js:30
node_modules/react-dnd/dist/esm/hooks/useDrag.js:30:51
- DraggableCard.js:22
src/components/cards/DraggableCard.js:22:41
対応
エラーメッセージにある通り、https://gatsby.dev/debug-html に書かれている方法で対応できました
useDragやuseDropを呼び出しているところに (typeof window === `undefined`)
による処理を追加しました
const [{ isDragging }, drag] = (typeof window === `undefined`) ? [{}, null]
: useDrag({
item: { type: ItemTypes.TYPE },
collect: monitor => ({
isDragging: !!monitor.isDragging(),
}),
})
原因
DndProviderの読み込みと配置を gatsby-browser.js
で行っていたためでした
gatsby-browser.js
const DndProvider = require('react-dnd').DndProvider
const HTML5Backend = require('react-dnd-html5-backend').HTML5Backend
exports.wrapRootElement = ({ element }) => {
return (
<DndProvider backend={HTML5Backend}>
{element}
</DndProvider>
)
}
全ページで使用しているラッパーコンポーネントの <Layout />
内に配置することでビルドエラーが出なくなりました
ただ、この方法にすると、別の場所でCannot have two HTML5 backends at the same time.
が出てしまいウェブアプリがクラッシュしてしまいます
さいごに
コンポーネントを再起的に呼び出したりしているためか、エラーの根本的な原因は不明でした
ビルドを通すためだけの処理を追加したような感じでスッキリしませんが、とりあえず解決
React-dndの実装方法はこちらが完結で分かりやすかったです
https://qiita.com/hotchpotch/items/39da4b84da615b24a11f