Virtual DOM を使ったフロントエンドライブラリである deku のバージョン1.0がリリースされたようなので使ってみます。
インストール
Browserify と Babel を使うのでインストールします。 JSX のためのプラグインもいれて起きます。
deku
だけでなく virtual-element
も必要です。
$ npm install -g browserify
$ npm install -D babelify babel-preset-es2015 babel-plugin-transform-react-jsx
$ npm install -S virtual-element deku
Hello, World!
まずは Hello, World! から
// a.js
import { render, tree } from 'deku';
import element from 'virtual-element';
let Greeting = {
render() {
return <div>Hello, {props.children}!</div>;
}
};
render(tree(<Greeting>deku</Greeting>), document.querySelector('div'));
これをビルドするための .babelrc
ファイルが以下です。
{
"plugins": [
["transform-react-jsx", { "pragma": "element" }]
],
"presets": [
"es2015"
]
}
browserify -t babelify -o bundle.js a.js
コマンドで bundle.js
をビルドできます。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
</head>
<body>
<div></div>
<script src="bundle.js"></script>
</body>
</html>
この HTML を開くと Hello, deku!
と表示されます。
タイマー処理
setTimeout
を仕込んで表示する内容を変更してみます。
import element from 'virtual-element';
import { render, tree } from 'deku';
const timeoutId = Symbol();
let Greeting = {
initialState(props) {
return {
content: props.children
};
},
render({ state }) {
return <div>Hello, {state.content}!</div>;
},
afterMount(component, element, setState) {
component[timeoutId] = setTimeout(() => {
setState({ content: 'virtual DOM' });
}, 1000);
},
beforeUnmount(component) {
clearTimeout(component[timeoutId]);
}
};
render(tree(<Greeting>deku</Greeting>), document.querySelector('div'));
最初に initialState
が呼び出されます。そこで作った state
を使ってレンダリングします。
afterMount
が実際に DOM が作られたあとに呼び出されるのでそこで setTimeout
を仕込みます。 DOM が消される時に beforeUnmount
が呼び出されるので、無駄なタイマーが残らないように clearTimeout
を忘れないようにしておきます。
これをビルドして1秒待つと Hello, virtual DOM!
と表示されます。
クリックイベント
クリックに反応するコードも書いてみます。
import element from 'virtual-element';
import { render, tree } from 'deku';
let Greeting = {
initialState(props) {
return {
content: props.children
};
},
render({ state }) {
const onClick = (event, component, setState) => {
setState({ content: 'mouse' });
};
return <div onClick={onClick}>Hello, {state.content}!</div>;
}
};
render(tree(<Greeting>deku</Greeting>), document.querySelector('div'));
クリックイベントは onClick
プロパティに関数を入れるとハンドルできるようです。
これを表示してテキストをクリックすると Hello, mouse!
という表示に変わります。
さいごに
deku で Virtual DOM を試してみました。
React と違い render
メソッドのあるオブジェクトを作るだけでいいので軽く使えそうです。