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
2. Blocklyのインストール
Blockly公式のnpmパッケージを入れます。
$ npm install blockly
記事を書いている時点ではこのバージョンが入りました。
{
"dependencies": {
...
"blockly": "^3.20200924.3",
...
},
}
3. 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が更新された後に実行するようにしています。
画面は問題なく出ていますが、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を消す
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エディタの画面も問題なく使えます。