LoginSignup
5
2

More than 3 years have passed since last update.

ReactからBlocklyを使ってみた

Last updated at Posted at 2020-10-21

Qiita初投稿です。ReactでBlocklyエディタを表示させるまでの手順を紹介します。
使用環境はこんな感じ。

$ npm -v
6.14.8
$ create-react-app --version
3.4.1

1. create-react-appする

Reactプロジェクトの作成にはcreate-react-appを使用しました。

$ create-react-app blockly-react
(省略)
Happy hacking!

とりあえずちゃんと作成できているかテスト

$ cd blockly-react
$ npm start

自動的にブラウザが開いて以下の画面が出ていればOKです。
スクリーンショット 2020-10-22 1.29.54.png

2. Blocklyのインストール

Blockly公式のnpmパッケージを入れます。

$ npm install blockly

記事を書いている時点ではこのバージョンが入りました。

package.json
{
  "dependencies": {
    ...
    "blockly": "^3.20200924.3",
    ...
  },
}

3. App.jsの編集

App.jsに元々入っているコードは使わないので消し、まずは愚直に以下のコードで試してみます。

App.js
import React, { useEffect } from 'react';
import Blockly from "blockly";

function App() {
    useEffect(() => {
        Blockly.inject("blocklyDiv", {
            toolbox: document.getElementById("toolbox")
        });
    });

    return (
        <div>
            <div id="blocklyDiv" style={{width: "1024px", height: "600px"}}></div>

            <xml id="toolbox" style={{display: "none"}}>
            <category name="Loops" colour="%{BKY_LOOPS_HUE}">
                <block type="controls_repeat_ext">
                    <value name="TIMES">
                        <block type="math_number">
                            <field name="NUM">10</field>
                        </block>
                    </value>
                </block>
                <block type="controls_whileUntil"></block>
            </category>
            <category name="Math" colour="%{BKY_MATH_HUE}">
                <block type="math_number">
                    <field name="NUM">123</field>
                </block>
            </category>
            <category name="Text" colour="%{BKY_TEXTS_HUE}">
                <block type="text"></block>
                <block type="text_print"></block>
            </category>
        </xml>

        </div>
    );
}

export default App;

Blockly.injectはblocklyDivやtoolboxの要素を参照するので、useEffectを使用することでDOMが更新された後に実行するようにしています。
スクリーンショット 2020-10-22 1.51.05.png
画面は問題なく出ていますが、Chromeのコンソールを見ると大量のWarningが...。
そのうちの1つは、
Warning: The tag <xml> is unrecognized in this browser. If you meant to render a React component, start its name with an uppercase letter.
だそうです。
他のWarningも似たようなもので、xmlやcategory、blockなどのタグを使っているのが理由のようです。

4. Warningを消す

App.js
import React, { useEffect } from 'react';
import Blockly from "blockly";

function App() {
    const xml = `
        <xml id="toolbox">
            <category name="Loops" colour="%{BKY_LOOPS_HUE}">
                <block type="controls_repeat_ext">
                    <value name="TIMES">
                        <block type="math_number">
                            <field name="NUM">10</field>
                        </block>
                    </value>
                </block>
                <block type="controls_whileUntil"></block>
            </category>
            <category name="Math" colour="%{BKY_MATH_HUE}">
                <block type="math_number">
                    <field name="NUM">123</field>
                </block>
            </category>
            <category name="Text" colour="%{BKY_TEXTS_HUE}">
                <block type="text"></block>
                <block type="text_print"></block>
            </category>
        </xml>
    `;

    const xmlParser = new DOMParser();
    const xmlDom = xmlParser.parseFromString(xml, "text/xml");

    useEffect(() => {
        Blockly.inject("blocklyDiv", {
            toolbox: xmlDom.getElementById("toolbox")
        });
    });

    return (
        <div>
            <div id="blocklyDiv" style={{width: "1024px", height: "600px"}}></div>
        </div>
    );
}

export default App;

jsx内に直接xmlを書くのではなく、文字列からパースするアプローチで行きました。
これでWarningも出ずにBlocklyエディタの画面も問題なく使えます。

5
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
2