😽

Reactバージョン18でreact-beautiful-dndが使えない問題を解決する

2022/07/28に公開
1

はじめに

react-beautiful-dnd はドラッグアンドドロップが簡単に実装できる便利なライブラリです。
ですが React バージョン 18 以降にはサポートされていません。
そこでサポートされているバージョン 16 や 17 にして実装するのも良いのですが、
バージョン 18 でも実装できる方法を調査しましたのでここに記載していきたいと思います。

追記

現在(2023/8/6)ではこちらのIssueでReactバージョン18でもインストールできるようです。コメント頂きありがとうございます。
https://github.com/atlassian/react-beautiful-dnd/issues/2388
それでもインストールできない場合のみ以下を読み進めてください。

React バージョン 18 以降ではインストールできない

React バージョン 18 準備

create-react-app して React を準備します。
完了後、pacjage.json 見ると React バージョン 18.0.2 がインストールされています。
packagejsonBrefore

react-beautiful-dnd をインストール

ここで以下のコマンドで react-beautiful-dnd をインストールしてみます。

$ npm install react-beautiful-dnd

するとこのような感じでエラーになってしまいます。

npm ERR! code ERESOLVE
npm ERR! ERESOLVE unable to resolve dependency tree
npm ERR!
npm ERR! While resolving: プロジェクト名@0.1.0
npm ERR! Found: react@18.2.0
npm ERR! node_modules/react
npm ERR!   react@"^18.2.0" from the root project
npm ERR!
npm ERR! Could not resolve dependency:
npm ERR! peer react@"^16.8.5 || ^17.0.0" from react-beautiful-dnd@13.1.0
npm ERR! node_modules/react-beautiful-dnd
npm ERR!   react-beautiful-dnd@"*" from the root project
npm ERR!
npm ERR! Fix the upstream dependency conflict, or retry
npm ERR! this command with --force, or --legacy-peer-deps
npm ERR! to accept an incorrect (and potentially broken) dependency resolution.
npm ERR!
npm ERR! See /Users/ユーザー名/.npm/eresolve-report.txt for a full report.

npm ERR! A complete log of this run can be found in:
npm ERR!     /Users/ユーザー名/.npm/_logs/2022-07-27T13_46_41_808Z-debug-0.log

エラー内容を見ると、react-beautiful-dnd の最新バージョン 13.1.0
React バージョン 16.8.5 から 17.0.0 に対応しているとのこと。

解決方法

インストール

React のバージョンを 17 まで落とせばインストールできますが、
せっかくなら Reactバージョン 18 で開発したい、ということでさらにエラー内容をみてみます。
依存関係の競合を修正する場合は、実行したコマンドに--forceもしくは--legacy-peer-depsつけて再実行してね、
と記載があるので以下のコマンドに修正して再実行してみます。

$ npm install react-beautiful-dnd --legacy-peer-deps

これでエラーなくコマンドが完了できたのでpackage.jsonを確認します。
packagejsonAfter

さらにコード修正も必要

ここまででインストールできましたのでドラッグアンドドロップできるか確認します。
react-beautiful-dnd を使用したリストをテスト的に作成してみます。

TestList.js
export const TestList = [
  {
    id: "01",
    name: "みかん",
  },
  {
    id: "02",
    name: "りんご",
  },
  {
    id: "03",
    name: "ぶどう",
  },
  {
    id: "04",
    name: "メロン",
  },
];
App.jsx
import { useState } from "react";
import { DragDropContext, Draggable, Droppable } from "react-beautiful-dnd";
import { TestList } from "./TestList";
import "./App.css";

function App() {
  const [testList, setTestList] = useState(TestList);
  const onDragEndTest = (result) => {
    const items = [...testList];
    const deleteItem = items.splice(result.source.index, 1);
    items.splice(result.destination.index, 0, deleteItem[0]);

    setTestList(items);
  };

  return (
    <div className="App">
      <h1>ドラッグアンドドロップ</h1>
      <DragDropContext onDragEnd={onDragEndTest}>
        <Droppable droppableId="droppableId">
          {(provided) => (
            <div
              className="testListArea"
              {...provided.droppableProps}
              ref={provided.innerRef}
            >
              {testList.map(({ id, name }, index) => {
                return (
                  <Draggable key={id} draggableId={id} index={index}>
                    {(provided) => (
                      <div
                        className="testItem"
                        ref={provided.innerRef}
                        {...provided.draggableProps}
                        {...provided.dragHandleProps}
                      >
                        <div>
                          {id}{name}
                        </div>
                      </div>
                    )}
                  </Draggable>
                );
              })}
              {provided.placeholder}
            </div>
          )}
        </Droppable>
      </DragDropContext>
    </div>
  );
}
export default App;

react-beautiful-dndの書き方はこちらを参考にさせて頂きました。
https://dev.classmethod.jp/articles/react-beautiful-dnd-react-ts/

これでブラウザでドラッグアンドドロップしてみようとすると
文字列が選択されるだけでドラッグアンドドロップすることができません。
DragAndDropgifNG

この問題を解決するために色々調査してみると、
ReactStrictModeで動いていることが原因のようです。
StrictModeについてはこちらを参照ください[React ドキュメント]
https://ja.reactjs.org/docs/strict-mode.html

ということで、index.js<React.StrictMode>を削除して修正してみます。

修正前

index.js
import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
  <React.StrictMode>
    <App />
  </React.StrictMode>
);

修正後

index.js
import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
    <App />
);

修正後ブラウザでドラッグアンドドロップしてみると
無事ドラッグアンドドロップすることができました。
DragAndDropgifOK

まとめ

react-beautiful-dndReact バージョン 18 で使えないものかと考えていたところ
まとまっているサイトがなかったので色々調査した結果を今回この記事にしてみました。
同じような悩みを持っている方の参考になれば嬉しいです。

参考サイト

https://github.com/atlassian/react-beautiful-dnd/issues/2426

https://github.com/atlassian/react-beautiful-dnd/issues/2399

GitHubで編集を提案

Discussion