React Code Reading #1

React Code Reading

1st day. Read Preact h function. h is hyperscript which generate HyperText from JavaScript code. It's different from Shadow DOM. Shadow dom enables an encapsulated scope of styles. Styles declared within shadow DOM only applies the DOMs under shadow-root.

Virtual DOM is a JavaScript object having the information of real DOM tree. For example, VDOM equivalent to the DOM below needs to know three things.

<div id="root">Hello, world!!</div>
  1. The DOM root is div tag.
  2. The div tag has id of "root"
  3. The div tag has string "Hello, world!!" as a child.

Following JavaScript object describes these information

const rootNode = {
  tagName: 'div',
  attributes: {
    id: 'root'
  },
  children: ['Hello, world!!']
}

This object knows everything to render above HTML. hyperscript consumes virtualDOM object and produces an actual html.


Reading h function of preact. h function of preact consumes root VNode (node of Virtual DOM) and produces whole VDOM tree. In React or other similar view libraries, they let us make Components to reuse and encapsulate single VNode. For example, the Button function below can be used anywhere.

const Button = (attributes, children) => ({
  tagName: 'button',
  attributes: attributes,
  children: children
})
const rootNode = {
  tagName: 'div',
  attributes: {
    id: 'root'
  },
  children: ['Hello, world!!', Button({className: "primary-button"}, "Click me!")]
}

For the sake of ease, we use JSX to write Components in the same manner as HTML. Using JSX, the above code can be written like this.

const rootNode = <div>
  Hello, world!!
  <Button className="primary-button">Click me!</Button>
</div>

When React renders the VDOM tree in real DOM, they need to expand all those Components until all VNode are expressed in primitive DOM types provided by browsers(ex. div, a, p, etc). In preact h function, it actually does not produce HTML string but produces VDOM used in preact.


Let's dive into the real code.

import { VNode } from './vnode';
import options from './options';

const stack = [];

const EMPTY_CHILDREN = [];

export function h(nodeName, attributes) {
    let children=EMPTY_CHILDREN, lastSimple, child, simple, i;
    for (i=arguments.length; i-- > 2; ) {
        stack.push(arguments[i]);
    }
    if (attributes && attributes.children!=null) {
        if (!stack.length) stack.push(attributes.children);
        delete attributes.children;
    }
    while (stack.length) {
        if ((child = stack.pop()) && child.pop!==undefined) {
            for (i=child.length; i--; ) stack.push(child[i]);
        }
        else {
            if (typeof child==='boolean') child = null;

            if ((simple = typeof nodeName!=='function')) {
                if (child==null) child = '';
                else if (typeof child==='number') child = String(child);
                else if (typeof child!=='string') simple = false;
            }

            if (simple && lastSimple) {
                children[children.length-1] += child;
            }
            else if (children===EMPTY_CHILDREN) {
                children = [child];
            }
            else {
                children.push(child);
            }

            lastSimple = simple;
        }
    }

    let p = new VNode();
    p.nodeName = nodeName;
    p.children = children;
    p.attributes = attributes==null ? undefined : attributes;
    p.key = attributes==null ? undefined : attributes.key;

    // if a "vnode hook" is defined, pass every created VNode to it
    if (options.vnode!==undefined) options.vnode(p);

    return p;
}

This is the real code of h function in preact. It does quite simple stuff. It just consumes the Object provided by user and returns the VNode object. Simple is that.


References
React Components, Elements, and Instances
Reconciliation
仮想DOMの内部の動き
virtual-dom

axiosでPOST

axiosでpostするとContent-Typeがapplicaiton/jsonになってしまう。 content-type: x-www-form-url-encodedで送るためにURLSearchParamsを使うのが推奨されているっぽい。 safariに対応するためpolypillを利用した。

URLSearchParamsのpolypillとして https://github.com/WebReflection/url-search-params を使う。

create-react-appでapplicationを作成してるため、yarn run eject後にconfig/polyfill.jsに

window.URLSearchParams = require(‘url-search-params’);

を記述すればok。 これでGlobalでURLSearchParamsがpolyfillしてくれる。

OLD BOY見た

韓国映画のOLD BOYを見た。

はじめは映像の感じとか、安っぽいアクションシーンとか、B級映画感がすごかったのだが、終盤の展開は衝撃的。 ストーリーは、主人公が15年監禁されるところから始まり、15年後にその相手に復讐する話。 監禁が解けたあと助けてくれるヒロインがとてもかわいいのだが、そのヒロインと主人公はとても悲しく終了する。

直接の描写はないがグロもあるので注意。

良くも悪くも衝撃的。アメリカ版もあるみたいなので今度見てみようかな。

夜は短し歩けよ乙女。読んだ

夜は短し歩けよ乙女を読んだ。 森見登美彦の07年の作品で、大学生の女の子とその先輩との追いかけっこの話。

爽やかで京都っぽい文体がテンポよく心地いい。 ストーリーはベタな恋愛モノっぽく進むんだけど、登場人物もキャラが立ってておもしろい。 あとは、とにかく主人公の女の子がかわいくておすすめ。

君の膵臓が食べたいよりずっといい。

アヒルと倉庫

Reduxでフロントエンドを書いているといつも思うのがそのboilerplateの多さ。そこで、actionなりreducerなり関心ごとをまるっと一つのファイルにまとめちゃおうというducksという指針が提唱された。

これはこれで壁もあるみたいなんだけど、boilerplateの煩わしさを考えるとけっこう良さそうなので、取り入れてみようと思う。

あとNerflixの人のトークみてからRxも気になってる。observableもちょっと触ってみよう。

Scheme

SICPを読んでみようと思って購入したはいいものの、コードがSchemeで記述されててなかなか読めないので、Little Schemerからやることにした。

括弧が多くてはじめは見慣れないし、S式とかもよくわかんなかったけど、再帰とか当たり前のように最初っからバンバン出てきてて楽しい。

SICP読むぞ!!

例示は理解の試金石

僕の好きな本に、プログラマであり作家の結城浩さんの数学ガールというシリーズがある。

主人公である"ぼく"と、友達や後輩の女の子と数学の問題を考察していく一風変わったハーレム系のラノベであるが(ちがう。)、その中でも特に好きなフレーズに、『例示は理解の試金石』という言葉がある。このフレーズは物語中でたびたび登場し、彼らの数学的考察のキーワードだ。なにか問題を考えるときに、具体例を考えてみるとなにかきっかけがつかめるよ、という至ってシンプルだが、それだけにとても強力な考え方だ。

先日、起業に関する授業で視聴したビデオでこの言葉を強く実感したので、ぜひ紹介させてほしい。Airbnbの創業者Joe Gebbiaの創業時のエピソードで、どのように信頼をデザインするかというトークである。

How Airbnb designs for trust | Joe Gebbia

このビデオの中でスマートフォンをアンロックして隣りに座っている人に渡すシーン。これが赤の他人の信頼に関する素晴らしい例となって、観客を引き込んでいる。

これを参考にぜひ例示をうまく使って物事を考えていきたいものだ。