React-Grid-Layoutを使用して、Drag & Dropで移動でき、サイズの変更も可能なコンポーネントの実装を試してみます。
完成形は以下のようになります。
React-Grid-Layoutって?
React-Grid-Layout(以下RGL)はReact用のグリッドレイアウトです(まんま)。
上の画像のように、D&Dでコンポーネントの移動ができるようになります。
また、RGLのインストールにはreact-resizableというパッケージも含まれており、コンポーネントのサイズの変更も可能になります。
多分GitHubのREADME見れば実装するのも簡単だと思いますが、
React初めて一週間くらいなので、練習がてらまとめておきたいと思います。
GitHub
インストール
まずはパッケージをインストールします。
npm install react-grid-layout
インストール後、以下のCSSのインポートをどこかに追加しましょう。
今回はindex.jsでインポートしました。
import '../node_modules/react-grid-layout/css/styles.css';
import '../node_modules/react-grid-layout/css/styles.css';
実装
あとはコーディングしていくだけです。
今回は子コンポーネントを一つだけ用意して、propsだけ変えて何個か呼び出すような感じにしました。
先にコードを載せておきます。
React超初心者なので書き方間違ってるところとかあったらスミマセン。
import React from 'react';
import GridLayout from 'react-grid-layout';
import SampleComponent from './SampleComponent';
class App extends React.Component {
  constructor(){
    super();
    this.state = {
      cols : 12,
      rowHeight : 30,
      width :window.parent.screen.width
    }
    this.layouts = [
      {i: 'a', x: 0, y: 0, w: 2, h: 4},
      {i: 'b', x: 2, y: 0, w: 4, h: 4},
      {i: 'c', x: 6, y: 0, w: 2, h: 8},
      {i: 'd', x: 0, y: 4, w: 5, h: 5},
      {i: 'e', x: 0, y: 9, w: 5, h: 2},
      {i: 'f', x: 6, y: 11, w: 2, h: 2},
    ];
  }
  render(){
      return (
      <GridLayout className="layout" layout={this.layouts} cols={this.state.cols} rowHeight={this.state.rowHeight} width={this.state.width}>
        <div key="a" style={{border:"solid", backgroundColor:"#EEEEEE", textAlign:"center"}}><SampleComponent componentName="A" /></div>
        <div key="b" style={{border:"solid", backgroundColor:"#EEEEEE", textAlign:"center"}}><SampleComponent componentName="B" /></div>
        <div key="c" style={{border:"solid", backgroundColor:"#EEEEEE", textAlign:"center"}}><SampleComponent componentName="C" /></div>
        <div key="d" style={{border:"solid", backgroundColor:"#EEEEEE", textAlign:"center"}}><SampleComponent componentName="D" /></div>
        <div key="e" style={{border:"solid", backgroundColor:"#EEEEEE", textAlign:"center"}}><SampleComponent componentName="E" /></div>
        <div key="f" style={{border:"solid", backgroundColor:"#EEEEEE", textAlign:"center"}}><SampleComponent componentName="F" /></div>
      </GridLayout>
    );
  }
}
export default App;
import React from 'react';
import './App.css';
class SampleComponent extends React.Component{
    render(){
        console.log(this.props);
        return (
            <div>
                <h3>Component {this.props.componentName}</h3>
            </div>
        );
    }
}
export default SampleComponent;
親のGridLayout要素で囲んだ部分がグリッドレイアウトになります。
layout属性にあらかじめ子コンポーネントの位置を指定しておくようにします。
これでなんとなく機能を試すことができます。
しかしこれ、ページ表示時やリフレッシュ時にコンポーネントを移動させようとすると、
全コンポーネントが一瞬だけ浮き上がったような挙動をするんですよね…
自分のやり方がどこか間違ってるのかなんなのか…
ちょっとここは後で調べておかないとですね。
