今日はお休み
色々ありましたです。ハイ。
とりあえずこの猛暑はどうにかならんものかな。。。。
Reactでグラフ作るの巻
rechartsってやつを使ってとりあえず棒グラフを作っています。
X軸を表現するコンポーネントが<XAxis>
ってやつなんですが、
歯抜けなデータだと全てのlabel(tick?)が表示されないことがあるっぽいです。
その時はとりあえず以下のようinterval={0}にしておくとよいです。
<XAxis dataKey="name" interval={0} />
表データからツリー構造への変換(深さ優先探索)
できた。
深さ優先探索を使っています。
まずルートとなる要素を確定し、その要素に子要素を追加し、その子要素の子要素を…を繰り返しています。
昨日やってたのは、終端要素から親となる要素を追加していくという方法でしたが、
うまいこといかんかったので、今日は逆に子要素を追加していく方法でトライしました。
1時間もかからなかったかな。
class Converter { convertToTree(nodes) { const rootNodes = nodes.filter(node => !node.parentID) const rootNode = rootNodes[0] rootNode.children = this.buildChildNode(rootNode, nodes) console.log('result', rootNode) } /** * Depth first search * @param {*} parentNode * @param {*} nodes */ buildChildNode(parentNode, nodes) { const parentNodeID = parentNode.id const childNodes = [] nodes.forEach(node => { if (node.parentID === parentNodeID) { childNodes.push(node) if (node.hasChild) { node.children = this.buildChildNode(node, nodes) } } }) return childNodes } }
表データからツリー構造への変換
末尾の表データをツリー構造に変換したく色々トライしていますがうまくいかぬorz
枝の深さの数がそれぞれ違うので途中でおかしくなって破綻するパターン。
週末は普通に休みだし、いい頭の体操になるかなー。
Id | parentID |
---|---|
1 | |
2 | 1 |
3 | 1 |
4 | 1 |
5 | 1 |
6 | 2 |
7 | 6 |
8 | 6 |
9 | 6 |
10 | 3 |
11 | 3 |
12 | 3 |
13 | 3 |
14 | 4 |
15 | 14 |
16 | 15 |
17 | 4 |
18 | 5 |
19 | 15 |
20 | 19 |
21 | 19 |
22 | 19 |
23 | 19 |
Reactでwhy-did-you-update
お前は何故更新されたんだ?
why-did-you-updateというReactのレンダリング状況をログ出力してくれるライブラリがあります。
使い方
アプリのソースコードに以下コードを書きます。どこでもいいです。
さしあたってはエントリーポイントとなるindex.jsか、ReactDOM.renderを最初に定義しているところに書けばいいのではと思います。
import React from 'react'; if (process.env.NODE_ENV !== 'production') { const {whyDidYouUpdate} = require('why-did-you-update'); whyDidYouUpdate(React); }
使ってみた
このようなログが出ます。Google Chrome Developer Toolなどから容易に確認出来ます。
例をパクらさせて頂きましたが、実際に開発しているアプリケーションに適用するとかなりログが出ること出ること請け合いです。
レンダリング前後のprops, stateの値が確認しやすくなっています。
こいつらの値をshouldComponentUpdateの中で比較してレンダリングする/しないの判断をすることになるかと。
ただ、気をつけて欲しいのが、shouldComponentUpdateを既にコンポーネントに組みこんでいる場合、why-did-you-updateさんが空気を読んでくれます。
次からそのコンポーネントのログが出なくなっちゃいます。
仕組みとしてはAOPっぽい感じがしました。
まとめ
Reactで高パフォーマンス、快適なUXを出すにはいかにコンポーネントのレンダリングを減らすかにもかかっていると思うので、
why-did-you-updateは役立ちます。
ES2015でPrototype
色々残念だ。心より恥じるしかない。
class Product { use(str) {} createClone() {} } class Manager { constructor() { this.showcase = new Map() } register(name, product) { this.showcase.set(name, product) } create(name) { const product = this.showcase.get(name) return product.createClone() } } class MessageBox extends Product { constructor(decoChar) { super() this.decoChar = decoChar } use(str) { const length = str.length let char = '' for (let i = 0; i < length + 4; i++) { char += this.decoChar } console.log(char) console.log(`${this.decoChar} ${str} ${this.decoChar}`) char = '' for (let i = 0; i < length + 4; i++) { char += this.decoChar } console.log(char) } createClone() { return this } } class UnderLinePen extends Product { constructor(ulchar) { super() this.ulchar = ulchar } use(str) { const length = str.length console.log(`\" ${str} \"`) let char = '' for (let i = 0; i < length; i++) { char += this.ulchar } console.log(char) } createClone() { return this } } const manager = new Manager() const upen = new UnderLinePen('~') const mbox = new MessageBox('*') const sbox = new MessageBox('/') manager.register('strong message', upen) manager.register('warning box', mbox) manager.register('slash box', sbox) const p1 = manager.create('strong message') p1.use('Hello, world') const p2 = manager.create('warning box') p2.use('Hello, world') const p3 = manager.create('slash box') p3.use('Hello, world')
一番の残念ポイントは、オブジェクトのコピーをしていないところ…。
当初、Object.assign(...)を使っていたのですが、フィールドしかコピーされないんですね。(俗にいうシャローコピー)
Function含めてコピーする方法として、lodashやjQuery使うってのもありましたが、
雑に対応しちゃいました。
ES2015でSingleton
イマイチ感がすごすぎる…。
class Singleton { constructor() {} echo() { console.log('hello') } static getInstance() { if (Singleton.instance === null) { Singleton.instance = new Singleton() } return Singleton.instance } } Singleton.instance = null const instance1 = Singleton.getInstance() const instance2 = Singleton.getInstance() console.log(instance1 === instance2) instance1.echo()
getInstance()経由で唯一のインスタンスもらえるのはまあいいのですが、
外からnew出来ちゃうのが問題ですねこれ。
どうSingletonを実現するのがスマートなんだろうか。