JavaScript
js
google
incremental-dom

はじめてのincremental-dom

More than 1 year has passed since last update.

はじめに

google/incremental-domはGoogleが開発しているDOMをレンダリングする為のライブラリです。

DOMを生成し、データの更新時は差分をレンダリングします。

virtualDOMとの違いDOMの生成時に大量にメモリーを消費しないそうです。

const component = data => {
  elementOpen('div')
  text(data)
  elementClose('div')
}

patch(document.body, component, data);
// <div>hello, world</div>

incremental-domには状態を管理するようなAPIがありません。
状態を受け取れるような関数やclassを設計すると良さそうです。

patchでレンダリングするのですが、再レンダリングの時もpatchを使用します。

patch(document.body, component, data);
patch(document.body, component, nextData);

2.6kB(min+gzip)しかないそうです。
既存のプロジェクトに部分的に組み込むことに期待できます。

サンプルコード

サンプルコードを用意しました。

$ git clone git@bitbucket.org:sankaku-io/qiita-incremental-dom.git

$ cd qiita-incremental-dom

distにコンパイル後のファイルを残しています。
動作はindex.htmlで確認できます。

コードを書き換える際はwebpackを使用してください。

$ npm i

$ npm start

incremental-domは0.4.1です。

index.js
import { observable, autorun } from 'mobx'

import {
    elementOpen, elementClose, elementVoid, text, patch
} from 'incremental-dom'

const observer = state => {
    elementOpen('span');
    text(state.count);
    elementClose('span');
    elementVoid('input', '', ['type', 'button'],
        'onclick', () => state.count -= 1,
        'value', '-1',
    );
    elementVoid('input', '', ['type', 'button'],
        'onclick', () => state.count += 1,
        'value', '+1',
    );
};

autorun(
    patch.bind(this, document.body,
        observer,
        observable({ count: 0 })
    )
);

サンプルコードは簡単なカウンターです。
「+1」と「-1」があるので、クリックすると数字が変わります。

incremental-dom

elementVoid

elementVoid('input')はinputタグをレンダリングしています。

import { elementVoid } from 'incremental-dom'

elementVoid('input', 'key',
  ['type', 'button'],
  'value', state.counter.count
)
<input type='button' value='0'>

引数は次のように設定されてます。

elementVoid(
   tagname, // string
   key, // string
   staticPropertyValuePairs, //Array
   propertyValuePairs, // vargs
)

keyはおそらく複数のコンポーネントから1つを識別する際に設定します。必要ない場合は''などでも構いません。

staticPropertyValuePairsは配列でプロパティと値を交互に設定します。おそらくtypeなどの更新される予定のないプロパティがstaticPropertyValuePairsになります。

[ 'class', 'btn', 'type', 'button' ]

propertyValuePairsは更新するプロパティやonclickなどのイベントリスナを設定します。こちらもプロパティと値を交互に設定しますが、配列ではなく可変長引数です。

elementOpen, elementClose, text

import { elementOpen, elementClose, text } from 'incremental-dom'

elementOpen('div')
text('hello world')
elementClose('div')

<div>hello,world</div>

閉じタグのあるものはelementOpenelementClose、テキストノードはtextです。

patch(target, container, data)

patch

patchすることでDOMがレンダリングされます。targetにはdocument.bodyなどのDOMをレンダリングする場所を設定します。containerdataを受け取ることのできる関数を設定します。

さいごに

incremental-domは資料が充実しています。
google.github.io/incremental-dom