旧gaaamiiのブログ

間違ったことを書いている時があります。コメントやTwitter、ブコメなどでご指摘ください

キウイの本を読んでる

キウイ🥝。

なんで読んでるのか

自分はいまウェブアプリケーションのUIをつくる仕事をしているので、ReactやらReduxの記事とかはよく読む。けどもう少し広めの、UIをつくるプログラミング全般に適用できる設計パターンみたいなのを学びたかった。

あとで感想ここに書く

Storybookを使って気付くCSSの粗さ

がっと作った大きなOrganismがあって、それを構成するMolelculeやらAtomやらのレベルのコンポーネントをすべてStorybookに置いた段階で、「あれ、なんかこれいい感じに表示できない...」ということに気付く。CSS Modulesを使ってスタイルのスコープをそのコンポーネントに閉じさせているものの、それだけでは期待する見た目にならない。正しい見た目が上の要素に依存していて、それがないとちゃんとした見た目にならない。直さなくては...ということになる。

Storybookに細かい単位でコンポーネントを置かなければこういうのをごまかせてしまうので、いざ細かいコンポーネントを使い回すときになるまで「なんだこれ」ということに気づかなかったりする。Storybookの使いみちはいろいろあるけど、こういうスタイルのスコープ確認につかえて便利だと思う。

fetch-mockでStorybookからモックデータを利用する

新たに開発している画面で、Storybookを利用してデザイナーさんに見た目のレビューしてもらいやすくしようとしている。この画面はAPIと並行して開発しているので、モックデータを用意してそれを見るようにする必要がある。

アプリケーション本体の方ではjson-serverを使っていて、Storybookもローカルで確認するにはそれで十分だったのだけど、確認のために用意した環境はS3なので、別でモックサーバーを立てるというのはそこまでするの感がある。

ferch-mockを使うと、APIへのリクエスト部分をモックのpromiseに差し替えられる。setTimeoutの値を変えれば遅いAPIをシミュレーションできるし、エラーを返せばエラー時の挙動を確認できる。便利。

json-serverのために用意したモックデータをそのまま使えてよかった。

ContainerコンポーネントとPresentationalコンポーネント、reduxとの接続についての方針とか

ReactとReduxでアプリケーション書いていて、containerコンポーネントとpresentationalコンポーネントの分け方どうするかという話。スマホで雑に書いているので、あとでまとめる。

元ネタ

redux作者のブログ記事のあれ。

参考にしたもの

AbemaTVの人のAtomic Designの本に書いてあった方法

コンポーネントの種類分けることで何ができるのか

もう少し詳しく

  • イベントが起きたときに何をするかというのをcontainer側に書いておいて、見た目のコンポーネントにはそれをpropsとして渡す
  • reduxのstateに変更を加えるような処理はactionを投げてreducerが処理をする
  • 見た目コンポーネントがそのコンポーネント自身でしか使わないような見た目のStateを持つのは許容する。
  • ファイルは今のところ分けずに、1ファイル内にcontainerもpresentationalも書いてる
  • reduxと接続するのはcontainer

elm/timeの使い方よくわからない問題

あるイベントが起きた時刻をサーバーに送信したい!というときに、Elmではどう書くのか調べたけどよくわからなくて、頑張って実現するとこういう感じになってしまったというメモ。これでいいのかよくわからない。サンプルを書いたので識者の知見がほしい...。

サンプル

疑問点

JSなら任意の時点で new Date()すれば現在時刻が取れるのだけど、Elmの場合はsubscriptionsに関数を入れて、一定間隔でmodelの値を更新して、使うときはその値を参照するみたいにしないといけないのか...?というところ。イベントが起きたときだけほしいのに、前もってそれをmodelに持って常に更新しておかないといけないのだとしたらなんか変な感じする。おれがやってることが間違ってるんじゃないか感がある。というのが現状。

Reduxのreducerはなんでreducerと呼ばれているのか

Reduxのreducerはなんでreducerなのか、そもそもreducerってなんだ、みたいなことを調べたので書きます。間違ったこと書いてたら直します。

背景

Reduxでは、reducerってやつが状態の変更方法を知っています。reducerはReduxのドキュメントに以下のように書いてある通り、

状態とアクションを受け取って、次の状態を返すやつです。

しかし、reducerという言葉はどういう意味なのでしょう。「状態とアクションを受け取って、次の状態を返すやつ」を、なぜreducerと呼ぶのでしょう。

Weblioの辞書で調べると、

〔+目的語+to+(代)名詞〕〈ものを〉(整理して)〔簡単な形に〕変える,まとめる.

という意味が出てきます。上述の通りReduxのreducerはstateを変えたものを返すやつなので、これが適切なのではないでしょうか。

ここで納得して終わりにしてもいいのですが、Reduxのreducerの意味がこれでよしとするには少し早いような気がします。Reduxの文脈で、なぜreducerという言葉が使われているのかをもう少し調べてみます。

Why is it called a reducer?

Google検索で、雑に why reducerと検索すると、先程のページが出てきます。

疑問に対する答えに当たる部分はここでしょうか。

It's called a reducer because it's the type of function you would pass to Array.prototype.reduce(reducer, ?initialValue).

ふむ。Array.prototype.reduce(reducer, ?initialValue)として渡せるような関数だからreducerと呼ばれている…?

なるほどわからん

Array.prototype.reduceの仕様

なるほどわからんなのは、私がArray.prototype.reduce関数を普段使っていないからのような気がします。reduceという関数に慣れていれば、上記の説明で一発理解ということになるのかもしれません。reduceは使ったこともあるし他の言語でもだいたいあるような一般的なものですが、ちゃんと仕様を読んで理解しているわけではありませんでした。

そこで、このreduce関数の仕様を見てみます。

さすがMDN、説明が丁寧です。これもじっくり読んでいきます。

reduce() はアキュムレータと配列の各要素に対して(左から右へ)関数を適用し、単一の値にします。

なるほどわからん。今度はまた新たななるほどわからんです。

今度のなるほどわからんは、「アキュムレータ」ってなんだ、という話です。こういうことを正直に書いてしまうとコンピュータのこと知らんやつだなというのが露呈するのであれなんですが、わからないものは仕方ない。

アキュムレータ(英: Accumulator)は、コンピュータにおいて、演算装置による演算結果を累積する、すなわち総和を得るといったような計算に使うレジスタや変数のことである。

accumulateというのが累積するという意味の英単語なので、そのままAccumulatorは累積するやつのようです。コンピュータアーキテクチャのことを学びたい気持ちも湧いてきてしまいますが、MDNのreduceのドキュメントを理解する上では、accumulatorという言葉の理解は上の説明で十分でしょう。

もう一度MDNのドキュメントに戻って、reduceが何をしているのかを見ていきます。

const array1 = [1, 2, 3, 4];
const reducer = (accumulator, currentValue) => accumulator + currentValue;

// 1 + 2 + 3 + 4
console.log(array1.reduce(reducer));
// expected output: 10

// 5 + 1 + 2 + 3 + 4
console.log(array1.reduce(reducer, 5));
// expected output: 15

Reduceの使い方として、上のコードが例示されています。配列内の数の総和を出しているだけです。

やっていること、使い方はわかりますが、どう動作しているのでしょう。それについても書かれています。

なるほどわかりました。accumulatorがそれまでの返り値を保持していて、currentValueが配列内の現在の要素です。

let array = [1,2,3,4];
let accumulator = 0;
for (let i = 0; i < array.length(); i++) {
  let currentValue = array[i];
  accumulator += currentValue;
}

for文で書くとこんなかんじでしょうか。外で宣言した変数に詰めるのではなく、引数として渡ってくるのでreduceのほうがすっきり書けます。

Array.prototype.reduce?

Array.prototype.reduceがやっていることはわかったものの、

It's called a reducer because it's the type of function you would pass to Array.prototype.reduce(reducer, ?initialValue).

これは結局どういうことでしょうか。ReduxのreducerがArray.prototype.reduce(reducer)として呼べるのであれば、reduceのレシーバに当たる配列は何になるんでしょうか?

Stack Overflowのある回答がとてもわかりやすかったです。

['INCREMENT', 'DECREMENT', 'INCREMENT'].reduce(reducer, 0)

つまりアクションの配列がレシーバになる。なるほど〜〜〜、そういうことを言っていたのか!0が最初のstate(accumulator)になり、reducerで定義された変更が3つ行われた結果が返ってくる。

雑感

Reducerというのが「stateを変えるためのあれ」くらいの認識だったけど、今回の調べで言葉の意味から理解できた。

ところで、reduceを調べているとfoldとか折り畳み関数みたいな言葉も出てきていた。次はここらへんについてもまとめてみたい。

参考リンクなど

RubyWorld Conference 2018 参加記(2日目)

shgam.hatenadiary.jp

1日目に続き、2日目も参加しました。

Chad Fowler氏の基調講演 Don't Stop Moving

エンジニアのキャリアなどについての話でした。そういえばまだちゃんと情熱プログラマー(Chadさんの本)を読んだことなかったので読みたくなりました。

mrubyについて

2日目はmrubyの話が多かったです。おもむろにrbenv install mruby-1.4.1してから話を聞いていましたが正直あまりついていけませんでした...。後でmrubyについて調べつつ発表の動画を見返したい。

2日間通しての感想

運営も会場も内容もすべてしっかりしたカンファレンスでした。

とても貴重な経験ができました。様々なRubyistと話すことができましたし、島根県松江市Rubyの関係とか雰囲気とか、そういったものも感じることができました。プログラミング言語で町おこしというのは先例もなかったと思うのですが、市がRubyの価値を理解してそれを利用してるというのがすごい。

また、自社のスタディプラスブースで好きなRuby本のアンケートを取っていたんですが、これがとても面白かったです。 Rubyのしくみ -Ruby Under a Microscope-が思ったより得票数多くて、さすがRubyWorld Conferenceだ...!という感じでした(青い付箋がRubyのしくみ)。

RubyのしくみはRuby構文解析とかの説明をした本なので、Rubyそのものに興味がある人達が集まっているこのカンファレンスでは人気が出るのもそれはそうか、とも思いましたが、それにしてもすごい。

自分はRubyのしくみをけっこう序盤で挫折してから読んでいないのですが、なんとかまた読み直そうと思いました。

2日間、自分は講演の聴講と自社ブースの案内だけで発表などはしていませんが、それでもとても貴重な経験ができました。 関係者の方々、スポンサーになってくれた自社に感謝です。ありがとうございました。

RubyWorld Conference 2018 参加記(1日目)

会社がスポンサーになったので、こちらに出席させていただいてます。

2018.rubyworld-conf.org

1日目のプログラムはまつもとゆきひろ氏の基調講演から始まり、Ruby Prizeの発表で終わりました。

Matz基調講演(The power of the community)

Rubyの父、Matzことまつもとゆきひろ氏の基調講演。

この基調講演では、Rubyがいつどのように生まれて、今日のように人気のある言語として広く使われるようになったのかを聴くことができました。

放置していたUTF-8対応、ドキュメント整備、ミートアップ開催、本の出版などはどれも、まつもとさん個人の力ではなくコミュニティの力で行われたことであり、特に人にプログラミングを教えるのはまつもとさんが苦手な部分だった(プログラミングできない人の気持ちがわからない)という話がありました。

また、こういったコミュニティの力を借りるために、コミュニティに対して面白いものを提供し続ける必要があるというようなことをおっしゃっていました。OSSコミュニティは止まったら死ぬ鮫のようなものだ、とも。

私はユーザーとして普段からOSSを使って仕事をしている身ですが、未だにOSSコミュニティは不思議に感じる部分が大きいです。仕事とも個人の趣味とも言えない、独特の雰囲気があります。

この基調講演でまつもとさんも、コミュニティに関わる人のモチベーションは知的好奇心、承認欲求、そこで発生するコミュニケーション、責任感、お金など人それぞれだとおっしゃっていました。

Ruby Prizeを受賞したk0kubunさんの発表

Ruby Prizeを受賞したk0kubunさんの発表も凄まじく良かったです。途中までブースにいて、内容を途中から聴いたのでYouTube動画あとで見返したい。

感想とか

今、Rubyはメジャーなプログラミング言語で、仕事はたくさんあり、学ぶ価値があるというのはすぐわかります。私も仕事で扱っているシステムはRubyで書かれていて、その開発や保守に携わって、日々生活するためのお金を頂いてます。Rubyで書かれたシステムが動いて、実際に価値を生み出していることは感じています。

しかし、そういったことが可能になる前からRubyそのものに携わってきた、作者のまつもとさんやコミュニティの中心で関わっている方々には、それとはまた違う気持ちがありそうです。

今日の講演などを聴いた上での私の想像ですが、知的好奇心を満たす手段として、純粋に楽しくてRubyに関わっていたのかなと、そんな風に思います。

何か技術的なことを学んだり、ものを作ったり、プログラムを書くことが、今の私にとっては仕事をしてお金を稼ぐためのものであり、それ自体が目的にはなっていません。しかし、もしそれ自体が目的になったり、少なくともそう感じられることが増えれば、とても幸せなことだと思います。

すごいエンジニアになってたくさんお金を稼ぐとか、偉くなりたいとか有名になりたいとか、そういったことではなく(もちろんそれも大事なんだけど)、やっていること作っているものそのものに没頭して、楽しさや喜びを見いだせるようなエンジニアになろう。基調講演やほかの素晴らしい発表を聴きながら、そんなことを考えることができました。

今さらReduxのSSOT原則とか状態管理について考える

Reduxを使ってウェブアプリケーションの開発をしていて、割と早い段階で、どうしてもReactのsetStateを呼びたい場面に遭遇しました。しかしReduxといえば、Single Source of Truthという原則があります。状態はすべて、Redux側で一つの状態ツリーで管理するものだと思っていました。

とすると、Reactコンポーネントたちは状態をpropsとして受け取って描画するだけ、ただのビューの関数であり、Reduxでの状態管理とReactでの要素表示の役割がしっかり分けられてきれいな世界になる...!!これがいまどきのきれいなウェッブアプリケーションなんじゃ!!!実装を始める前まではそんなものを想像していました。

ところが、実装を始めるとすぐにReactのsetStateを呼びたくなりました。それはもうすぐに呼びたくなりました。何かと言うと、いわゆるドロップダウンメニューの開閉表示状態です。今私が利用しているはてなブログの編集画面の、ここの部分みたいなものです。

クリックしたら開いたり閉じたりします。これ系の挙動をするコンポーネントは、だいたい何を作るにしても必要なものだと思います。

要は、この開閉状態を、Reduxで管理せず、Reactのそのコンポーネントのstateに持たせたくなったのです。

Reduxで管理する場合、きっと以下のようなコードが必要になります。

// components/DropdownComponent.jsx
const mapStateToProps = ...
const mapDispatchToProps = ...
export default connect(mapStateToProps, mapDispatchToProps)(DropdownComponent)

// actions/ToggleDropdown.js
export default {
  type: 'TOGGLE_DROPDOWN'
}
// reducers/toggleDropdown.js
const toggleDropdown = (state, action) => {
  switch(action.type) {
    case 'TOGGLE_DROPDOWN' :
    default:
      return !state
  }
}
export default toggleDropdown 

ふむ...ずいぶんと多くのファイルを編集しないといけない。

対して、ReactのsetStateを使う場合。

export default class DropdownComponent {
  constructor(props) {
    super(props)
    this.state = {
      visible: false
    }
  }

  handleClick = (e) => {
    this.setState({ visible: !this.state.visible })
  }

  render() {
    <div>
      <button onClick={this.handleClick}>
      {this.renderContent()}
    </div>
  }

  renderContent() {
    if (this.state.visible) { 
      return <DropdownContent />
    } else {
      return null
    }
  }
}

こりゃいいや!!!このコンポーネントのなかで完結していてわかりやすい!

しかし、そんなことをして怒られないのでしょうか。この軽はずみな実装によってReduxの怒りを買ってしまいプロダクトが破綻してしまっては困ります。

調べてみると、ちゃんとReduxにこんなFAQがありました。

(質問)

Do I have to put all my state into Redux? Should I ever use React's setState()?

まさしく自分が知りたいことです。setState呼んでいいのでしょうか?

(回答)

There is no “right” answer for this. Some users prefer to keep every single piece of data in Redux, to maintain a fully serializable and controlled version of their application at all times. Others prefer to keep non-critical or UI state, such as “is this dropdown currently open”, inside a component's internal state.

なるほど、、全部Reduxで管理するやつもいるし、ドロップダウンの開閉状態みたいなものに関してはコンポーネントに持たせる人もいるよね、と。答えになってないじゃないか!

Using local component state is fine. As a developer, it is your job to determine what kinds of state make up your application, and where each piece of state should live. Find a balance that works for you, and go with it.

それはお前が考えることだ、と。ふぉ〜〜〜。そうですよね〜〜。

改めて考えてみると、もともとはReduxなんかなくてもアプリケーションは作れる。じゃあなんでRedux使うのかというと、コンポーネントの中ではなくアプリケーション全体で持ち回したい状態を一箇所でちゃんと管理したいから、ということになる。それだってRedux使わなくてもできるわけだけど、そうするとバケツリレーと呼ばれるあの、状態とコールバックを受け渡し受け渡しする見通しの悪い地獄みたいなコードを書かないといけなくなる。それは嫌だ。それだったらReduxを使う、となります。

まとめ

ReduxのSingle Source of Truthを厳密に守ろうとするのはきついと感じることもあり、しかしReduxみたい状態管理ライブラリは何かしら必要です。自分の精進が足りず、まだベストな方法を見つけられていない感がありますが、Reduxを完璧なフレームワークと思い込まず、問題があったらそれについて考えながら使いこなしていければと思います。

「Atomic Design 〜堅牢で使いやすいUIを効率良く設計する」を読んでる

読んでいます。Twitterで気になったところをメモして、あとで感想などまとめたい。

エンジニアとデザイナーの設計方法の違いについて

インターフェースインベントリという手法があるらしい

コンポーネントをStorybookなどのカタログで管理することのメリットについて

コンポーネントリストに整理してあることでこんなことも可能になるんじゃという話

感想

具体的な実装の話が多くて良かった。わかりやすい。

第6章には、Atomic Designを現場でどう取り入れるかというような話が書かれていてためになる。

#builderscon 2018の感想

TL;DR

  • 9/6~9/8の3日間biuldersconに行っていろんな発表を聴いた
  • 最高だった

詳しく

9/6~9/8の3日間、biuldersconに行っていろんな発表を聴いてきました。聴いたセッションすべてではありませんが、気になったものだけブログ記事にメモを残したりしました。

shgam.hatenadiary.jp

shgam.hatenadiary.jp

shgam.hatenadiary.jp

全体の感想

本当にお祭りという感じで、終始楽しかったです。

全体通してmicroservicesの話が多く、各社試行錯誤しているんだなという印象を受けました。Envoyについては全く知らず、昨日のとても丁寧なセッションを聞いても理解できたとはいえない感じだけど、これがmicroservicesの課題を解決できるんだとしたら、今後必要になってきそう。

今回感じたカンファレンス参加の意義みたいなもの

また今回会社のスポンサーチケットで参加させてもらったので、楽しいというほかに、こういうカンファレンスへの参加が普段の業務の役に立つのか?ということも少し考えました。

技術的な価値や負債に真っ先に気付けるのはエンジニアなので、自信を持って決断をするために、こういうカンファレンスに知見とか失敗談を持ち寄って共有し合うのはすごい価値のあることだと思います。もちろん、聴くだけの人間としては、カンファレンスに行けば正解が得られるというわけではないし、行くだけで自分のスキルが向上するわけでもありません。しかし、こういう問題あるあるだよねーと言ってゲラゲラ笑う発表、真面目に解決策を模索する発表、失敗談の共有、全く新しいことへの挑戦などなど、様々なタイプの発表を聴くことができ、学べることは多かったです。

こういうお祭りが一切なくなってしまったら、我々は日々向き合ってる地味でつらい問題をどこで笑い飛ばせばいいんだ...?新しい技術を試している人や問題の解決策を知っている人を、どこで見つければいいんだ...?みたいな気さえします。

まとめ

運営の方々、登壇者の方々、スポンサーになってくれた弊社(この記述でいいんだろうか)、本当にありがとうございました。 初めてのbuilderscon参加でしたが、最高に楽しかったです。

#builderscon 2018 参加記(2日目)

shgam.hatenadiary.jp

shgam.hatenadiary.jp

前夜祭、1日目に続き、行きました。

聴いた発表

  • 「Web とは何か?」 - あるいは「Web を Web たらしめるものは何か?」
  • すべてが gem になる - サービス密結合からの段階的脱却
  • デザイナーとうまく協働する方法
  • Webアプリケーションエンジニアが知るべきDNSの基本
  • RDB THE Right Way ~壮大なるRDBリファクタリング物語~
  • LT

気になったセッション

「Web とは何か?」 - あるいは「Web を Web たらしめるものは何か?」

https://builderscon.io/tokyo/2018/session/476a4a30-2f94-424c-bbc2-f6cb14f1c4cdbuilderscon.io

Webのアーキテクチャの変遷から現状と課題を見直すという話。Webを(使う/で作る/を作る)人たち、三者で見ているものが違うという前提を念頭に話が進む。

もともとHyper Media Systemとしてのウェブだったのが、Ajaxの発見で出てきたセキュリティの問題をOriginの制約によって解決。そこからアプリケーションプラットフォームとして進化してきたウェブが、今やデバイスへのアクセスまで手を出してOS化していっているという話でした。

「Webで作る」立場のウェブアプリケーションエンジニアの中では、ウェブに携わるようになった時期によって、今でもHyper Media Systemとしてウェブを捉えている人と、Application Platformとしてのウェブを最初から受け入れているような人がいて、そのどちらの人にとっても、今後のウェブについてどう考えていったらいいかが整理されるような話だったと思います。個人的にはOSとしてのウェブというのはまだ受け入れられないけど、「Webを作る」人たちの間ではそこに向かってすでに議論が行われて、実際そっちに向かっているということは知ることができました。

デザイナーとうまく協働する方法

https://builderscon.io/tokyo/2018/session/fd38108a-123f-4ef1-9a05-d50be4118df6builderscon.io

デザイナーとうまく協働する方法。内容的には、デザイナーが(他職種と)うまく協働する方法っぽかったです。

「よい」というニュアンスを自分の中ではなく組織内で共有するためのプロセスが必要で、それに基づいてデザインの評価は行われるべき。そうでないと、デザインがセンスだったり好みだったり偉い人が決めるみたいな状況になってしまう。そうならないよう、徹底した言語化と文書化が必要。

たぶん多くの現場で、デザイナーなりエンジニアが「いい感じ」にやってしまっていると思います。「これどうですか?」という漠然としたコミュニケーションは、よっぽど細かいガイドラインを作らない限りは生まれそうです。

こちらの発表を聴いて、じゃあしっかり言語化ができているチームではそこらへんの情報をどうまとめているのだろうと興味が湧きました。今後、他社の取り組みで注目すべきなのは成果物のUI/UXだけじゃなく、そこに至るための言語化,文書化のプロセスだったり情報共有の方法だったりするのかなと思いました。

RDB THE Right Way ~壮大なるRDBリファクタリング物語~

https://builderscon.io/tokyo/2018/session/ddba9bd5-819e-489e-9123-04d2291d506ebuilderscon.io

テーブル設計やDBリファクタリングの話。 主にテーブルの正規化ちゃんとやろうという話でした。

以下の4冊が紹介されていて、SQLアンチパターンとRefactoring Databaseは持っていなかったのでとりあえず買ってみました。