Help us understand the problem. What is going on with this article?

ReactからBlocklyを使ってみた

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エディタの画面も問題なく使えます。

aquilaneo
首都圏の大学院生です。普段はthree.jsやBlockly、Electronあたりと戯れていますが、大学のプロジェクト活動で組み込みも少しかじっています。
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away