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>
- The DOM root is div tag.
- The div tag has id of "root"
- 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してくれる。
例示は理解の試金石
僕の好きな本に、プログラマであり作家の結城浩さんの数学ガールというシリーズがある。
主人公である"ぼく"と、友達や後輩の女の子と数学の問題を考察していく一風変わったハーレム系のラノベであるが(ちがう。)、その中でも特に好きなフレーズに、『例示は理解の試金石』という言葉がある。このフレーズは物語中でたびたび登場し、彼らの数学的考察のキーワードだ。なにか問題を考えるときに、具体例を考えてみるとなにかきっかけがつかめるよ、という至ってシンプルだが、それだけにとても強力な考え方だ。
先日、起業に関する授業で視聴したビデオでこの言葉を強く実感したので、ぜひ紹介させてほしい。Airbnbの創業者Joe Gebbiaの創業時のエピソードで、どのように信頼をデザインするかというトークである。
How Airbnb designs for trust | Joe Gebbia
このビデオの中でスマートフォンをアンロックして隣りに座っている人に渡すシーン。これが赤の他人の信頼に関する素晴らしい例となって、観客を引き込んでいる。
これを参考にぜひ例示をうまく使って物事を考えていきたいものだ。