もがき系プログラマの日常

もがき系エンジニアの勉強したこと、日常のこと、気になっている技術、備忘録などを紹介するブログです。

カイゼンジャーニーを読んだ

カイゼン・ジャーニー たった1人からはじめて、「越境」するチームをつくるまで

カイゼン・ジャーニー たった1人からはじめて、「越境」するチームをつくるまで

はじめに

こんばんは。連続です。

書こう書こうと思ってどんどん間が空いてしまったので、今日気合い入れて書きます。

書くまで寝ません。

中身

カイゼンジャーニーという本を読みました。

控えめに言っても最高でした。

内容がストーリー仕立てになっていたので、一回目は普通に小説を読むように読んでしまい、中身をきちんと腹に落とし込むためにもう一周読みました。

なんか、他の本みたいに気になるところだけを抜粋して紹介するっていう方法がいいかな?と思ったけど、それだけでは自分のなかでまとまりきらないので、ストーリーに沿って紹介したいと思います。

あまりに引用が過ぎたら、削除するかもしれません。

感想

第一章 一人から始める

概要

現状を変えたい良くしたいと思って、あれこれ提案しても周りの反応は今ひとつ。

そんな保守的なチームにも、変える時間を作れない炎上案件ばかりの会社にも嫌気がさして、転職しようと考えている主人公(江島)の話からスタートする。

とある社外イベントできいたセッションに感銘を受けて、発表者(石神)に話しかけるが、

「あなたは何をしている人なんですか?」

という一言に言葉がでず、その言葉の答えを探すために、行動を起こし始める。

最初は自分ひとりで、行動を起こす。

タスクマネジメント・タスクボード・朝会・ふりかえり。

はじめはうまくいっていたが、ひとりでの限界を知る。

そんなときにタイミングよく、ともに行動してくれる仲間(片瀬)が現れる。

ひとりからふたり。小さなチームができあがり、江島+片瀬の越境は加速していく。

感想

こういう状況って本当にあるあるだとおもう。

今の現場もまさにそう。

自分はある程度の数、現場を渡り歩いてきたから、もうこういう状況ってしょうがないって諦めるようになっている。

でも成長意欲が強い若い主人公には辛い現場だったと思う。

自分も20代かつ独身だったら、今の現場にはおそらくいないと思う。

社外イベントでの出会いがとても大事というのも、すごく共感できる。

今回のこの江島と石神の出会いのように、「人生が変わる出会い」というのものも普通にあるとおもうから。

それ以外にも業界トレンドを吸収することや、業界内での自分の位置の確認など、参加しないとわからないことが山のようにあるため、社外イベントへの参加はメリットしかないと思っている。

同じ場所にとどまって、毎日タスクをこなすだけの仕事ってなんだか味気ないし、自分の成長が見えにくい。

やっぱり新しいことにチャレンジすることが、成長の第一歩だと思う。

ただ、ここで重要なことが本では紹介されている。

外に出て知見を得ていくにあたって、覚えておかなければならない大事なことがある。外から得られた学びを、そのまま自分たちの現場や仕事で適用しようとしても、たいていうまくいかない。自分たちの「状況」に照らし合わせてみることが必要だ。

これも結構あるある。

「いいねこれ!取り入れてみようよ!」

っていうノリとテンションでやってみることってベンチャーの会社ではよく起こることだと思う。

↑のようなスピード感はとても自分好みだし、実際自分もこういうふうに提案したことがあった。

でも、絶対とは言わないけど、カチッとハマったことはあんまりなかった。

それはまさに「状況」が見えてなかったからだ。

ラクティスを紹介した会社(人物)の、実践した背景や制約などをきちんと理解せず、形だけを無理やり自分のチームに組み込もうとしていたからだ。

チームに組み込むということは、自分以外のメンバーも行うということ。

自分たちのチームにあうかどうかキチンと見極めて、実践しないといけない。

第一章で紹介されたTipsは、比較的有名なものだ。

だけど、一旦見返してみるととても良い気付きがあった。

1. タスクマネジメント

ざっくりいうと、ふられたタスクの目的を把握すること。

作業者的な意識の人や、新卒の子などは、ふられたタスクを一生懸命「終わらせる」ことを目的としているけど、それって本質を見誤っている。

本質は、よりよいサービスをユーザーに届けること。

なので、ふられたタスクの目的を理解することが重要。

本ではタスクマネジメントについて以下のように書かれている。

目的を明らかにしておくと、目的を達成するための段取りが不足していたり、遂行するためのスキルが足りていないことにも気づける。早めに気づけば打てる手もある。「うまくいかない要素」を早めに見つけることも、タスクマネジメントの大事な観点だ。

自分はこの他にも、以下のようなメリットがあると思う。

タスクをふる人も人間なので、時にはタスクの優先順位を間違えたり、「本質」と離れたタスクをふってしまうことがあるかもしれない。

タスクの目的を理解すれば、こちらから提案などができる。

「このタスクがこういう目的であれば、このアプローチがありますがどうでしょう?」

など、小さい会社であればあるほど、ひとりひとりの裁量権は大きいので、こういった提案も重要なものだと思う。

エンジニアのサービスの理解度も増すし、ひいてはよりよいサービスを作ることにつながるからだ。

ちなみに、今の現場ではgithub issueでタスクを管理しているが、カイゼンジャーニーを読んだ後、ISSUE_TEMPLATEに

「このissueの目的」

を記述するように変更を加えさせてもらった。

2. タスクボード

タスクの見える化

コレ大事だよね。人数増えてくると

「あいつ今何してるの?」

みたいなことが普通におきる。

やってることが見えなくて、何やってるかわかんないなら、見えるようにしてあげようってことだ。

ちなみに今の現場では、タスクボードはgithubのprojectsを使ってる。

f:id:kojirooooocks:20180602042216p:plain

こんな感じでステージごとに切り分けているので、チームメンバーにも好評。

他のチームメンバーも、それぞれprojectsがあり、このカタチがベースになっている。

3. 朝会

そのまま。

ただ、よくある朝会は、

「今日はコレやります」

みたいな、やることだけを淡々と述べていくものを想像していたが、本で紹介されている朝会は違った。

朝会では、昨日は何をやったのか?それを踏まえて今日は何をするのか?今日やることや計画を達成する上で困っていることはあるか?を整理する。整理した結果、もし計画とのズレが大きくなるようであれば、計画の立て直しを行う。

そうだよね。昨日なにやってて、今日はなにをやるっていうのを確認するのが正しい流れだと思う。

自分が今までいた現場でやっていた朝会って、今日コレやります。っていうタダの発表会みたいな感じだったので、正直、朝会の存在意義は自分の中で薄かったのだけど、これをみて大事だと再確認できた。

ただ、一点問題は自分がリモートで関わっているということ。

ここのベストプラクティスを知りたい。

常駐しろって答え以外で...

4. ふりかえり

これもそのまま。

作業のふりかえり。

ふりかえりのやり方で有名なのはKPTだ。

今の現場でも行っている。

  • Keep

    続けたいこと、やってみてよかったことをあげる

  • Probrem

    問題点、問題になる前の兆候や気付きなどもあげる

  • Try

    試したいことをあげる

勉強になったのは2回目のふりかえりについてだ。

2回目のふりかえりでは、前回のTryを見るところからスタートしよう。 Tryをやってみてどうだったのか?効果があって続けたほうが良さそうなら、Keepに移動させる。効果があるということは、Problemに変化が起きるということだ。問題の度合いが減じていたり、解消していたりするか、結果を捉えておこう。

前回のTryについては正直考えていなかった。

というより、Tryをやってみて、うまくいったらKeepにあがってくるでしょ?みたいな考えをしていたので、正直見逃していたものが多い。

このやり方を知ってから早速KPTにも取り入れてもらった。

ぶっちゃけ、今の現場にタスクボード・朝会・KPTを導入してもらったのは自分の発言からなのだが、それを「いいね!やってみようよ!」って即答してくれたデザイナーの@chups_cokeさんにはすごく感謝している。

現在は取捨選択しながら、今のチームにフィットするやりかたを一緒に探している。

こういうのも出会いだと思う。

自分の中での片瀬はまさに@chups_cokeさんだ。

第一章に関して、感じたところは以上だ。

物語的には、ひとりで行うことの限界を感じた江島に、片瀬という仲間ができて、二人で社内勉強会を開くという流れになっている。

ひとりで行っていたカイゼンが、仲間を巻き込み、大規模な社内勉強会を開くまでに成長する様は、正直感動モノだった。

第二章 チームで強くなる

概要

社内勉強会を開いてから1年が経ち、自信と経験がつき成長した、江島に、新たなプロジェクトへのアサインがきまる。

江島が尊敬する先輩(蔵屋敷)と行う新規プロジェクトは、社内プロジェクトで、江島がリーダーになり、チームを組んで開発を行っていくことになる。

個性の強いチームメンバー達と、見よう見まねで「スクラム開発」を行うが、スムーズに進まない。

そんななか、スクラムマスター(西方)がチームにアサインし、スクラム開発のイロハを教えてもらう。

時に遠回りかと思うような行動も、チームにとって、プロジェクトにとって、重要なことだということをチームメンバー・江島ともに理解し、文字通りスクラムを組んで開発を進めていく。

感想

正直この2章は、まだ理解しきれていない部分が多い。紹介されているTipsの数が多いからだ。

この章ではスクラム開発を前提に進められていく。

今の現場はスクラム開発を行っているわけではないし、自分自身でも経験がないので、1から勉強する必要があったのだが、自分の頭が悪いのかうまく理解できなかった。。。

なぜうまく理解できなかったかというと、

「既に運用フェーズに入っているようなプロジェクトでスクラム開発の動きを当てはめることが出来るのか」

というところだった。

これは今でもわかっていないので、誰か教えてほしい・・・

ただ、本で紹介されている、スクラム開発時に、起こる問題に対してのTipsは役に立つものばかりだった。

その中でも、個人的に、今すぐにでもチームに組み込めるなとおもった、ものを紹介したい。

1. Working Agreement

チームの中でのお約束みたいなこと。

このお約束は原則みんなが守ることになる。

スローガンのようなものは避けないといけない。

抽象的な言葉は、受け取り方が人によって違ってくるからだ。

  • チャットに30分以上応答できなくなるようなときは、事前に連絡する。
  • 週の残業が10時間を超えるような場合は、KPT時に必ず報告して、原因を話し合う。

など、明確なものをあげる。

更に重要だなと感じたのは以下だった。

こうしてチームの実際と合ったWorking Agreementは、新しいメンバーが参加する際にも、大いに役に立つ。チームが大事にしている価値観や行動規範を伝えやすくなるから、チームに溶け込む際の敷居を一気に下げられる。もっというと、中途採用面接などで、チームとの価値観が合うかどうかの判断にも使える。

たしかにそのとおりだ。

会社の雰囲気みたいなのは、大々的に紹介されているが、実際に入るチームの雰囲気は、入ってみないとわからない。

悲しいすれ違いをなくすためにも、今のチームメンバーの意識合わせのためにも、是非取り入れたいと思った。

2. ドラッカー風エクササイズ

チームメンバー同士の期待値の見える化ってイメージだと思う。

メンバーそれぞれが、

  • 何が得意なのか。

  • どうやってチームに貢献しようとしているのか。

  • 自分が大切に思う価値はなにか。

  • 他のチームメンバーは自分に何を期待していると思うか。

をあげていく。

否定をせず、ざっくばらんに、正直に書いてみる。

本では、プロダクトオーナーの土橋がwebアプリケーションの開発がほぼ初めてだということが、このドラッカー風エクササイズを行って気づいたことになっている。

ここまで衝撃的なことを発見できるかと言われると謎だが、3番目の「自分が大切に思う価値はなにか」という問いに対してのみんなの答えを聞いてみたいので、やってみたいと思った。

3. スキルマップ

簡単に言うと、プロジェクトで必要なスキルと、そのスキルを習熟度レベルをメンバー分つくって表にしてみるということだ。

このTipsですごくいいなと思ったのは、「習得希望」という項目を書ける点だった。

新卒メンバーは、勉強のために何でもやりますよ!っていう感じだと思うが、ある程度経験詰んだ人は、自分のroleモデルがなんとなく定まっていると思う。

そのうえで、どの分野を、今後伸ばすべきと思っているのかを見える化することが出来る。

たとえば、あまり興味が無いと思っているCSSとかをやらせても、仕事だからやるけれど本人も気乗りがしないし、スピードも遅いだろう。

それよりも、勉強中でもっと経験を積みたいと思っているpythonとかをやらせたほうが、意欲でるしもスピードも上がるはずだ。

ぜひやりたい。








これらが、第二章で知ったTipsで自分が実践したいと思ったものだ。

ただ、これらのほかにも良いものはいっぱいある。

とくに「むきなおり」は新規プロジェクトでは必須でやったほうがいいと感じた。

得てして長期プロジェクトでは、終着点が最初に考えていたところより、ぶれていくことがある。

それを軌道修正するためのTipsだ。

自分が新規開発にアサインされたときは、迷わずやりたいと思った。

第三章 みんなを巻き込む

概要

前回のプロジェクトをローンチまでもっていったことで、更に自信をつけた江島。

今度はクライアントがいる受注プロジェクトのリーダーを任されることになった。

プロジェクトのスタート序盤で、社内の別プロジェクトの影響で、チームメンバーの入れ替わりが発生し、社内リソースが足りず、フリーランスエンジニアに協力を求めることになる。

それ以外にもクライアントとの進捗確認やMTG、外部デザイン会社の人との打ち合わせなど、前回のプロジェクトでは発生しなかった事が次々と発生していく。

試行錯誤しながら、今まで行ってきたプラクティスを使い、プロジェクトを進めていく江島。

このプロジェクトの終わりに、彼が感じるものとは。

感想

3章は、社外の人を巻き込んでのカイゼンが主な話になる。

今の現場は、自社サービスの運用なので、現状関係があるわけではない。

しかし、3章で紹介されているTipsにもとてもよいものがあったので、紹介したいと思う。

1. プランニングポーカー

結構有名なので、わざわざやり方を紹介する必要もないと思う。

これは実は何回か、やりませんか?って提案したことがある。

見積もり工数をタスクごとに設定しているので、プランニングポーカーは相性が良いと感じたからだ。

ただ、実際にやるとなると、すべてのタスクでやるのか、それとも時間がかかりそうなタスクだけやるのかなどを決めたほうが良いと思う。

毎回やるの正直だるいしね。

でも、2〜3日かかりそうなタスクの場合、プランニングポーカーで他の人はどれくらいに終わると思っているのか、その理由は何かを聞けるのは、すごく重要だと思った。

それをきくことで、思わぬ解決策や、思わぬ障害に気づくことが出来るからだ。

もっかい提案してみようと思う。

2. CCPM(Critical Chain Project Management)

タスクの見積もりお願いします。

といわれて、3日で終わりそうだな〜と思っても、バッファをとって4日で設定した経験って絶対あると思う。

自分もしょっちゅうある。

ただそれって、全体的に見るとマイナスだよってこと。

本で紹介されているパーキンソンの法則がまさにそれだ。

仕事の量は完成のために与えられた時間を満たすまで膨張する、という法則です。大きく余裕を持って見積もったとしても、バッファというゆとりを追加したとしても、なくなっていきます。顧客側か開発側かにかかわらずです。一度期間が設定されてしまうと、その中で対処するように人間は考えてしまうわけですね。当初の計画時点でのバッファは、ただただ消費されていくだけなのです。

CCPMは、各タスクに対してはバッファを持たず、プロジェクト全体でバッファを持とうという考え。

プロジェクト全体のバッファはどれくらいかというと、プロジェクトに紐づくタスクの合計の見積もり工数の半分が妥当のようだ。

つまり以下のような感じ

  • 各タスクにバッファをもたせた場合

    • タスク1 = 工数: 5(実工数: 3, バッファ: 2)
    • タスク2 = 工数: 3(実工数: 2, バッファ: 1)
    • タスク3 = 工数: 2(実工数: 1, バッファ: 1)
    • タスク4 = 工数: 8(実工数: 5, バッファ: 3)
    • (3 + 2 + 1 + 5) + (2 + 1 + 1 + 3) = 18
  • プロジェクト全体にバッファをもたせる場合

    • タスク1 = 工数: 3(実工数: 3, バッファ: 0)
    • タスク2 = 工数: 2(実工数: 2, バッファ: 0)
    • タスク3 = 工数: 1(実工数: 1, バッファ: 0)
    • タスク4 = 工数: 5(実工数: 5, バッファ: 0)
    • (3 + 2 + 1 + 5) + ((3 + 2 + 1 + 5) / 2) = 16.5

全体で見ると工数が削減できるがわかる。

今関わっているのは運用フェーズのサービスなので、ここまでどでかい工数のタスクが来ることは稀だけど、来た際には実際にやってみたいと思う。

おわりに

自分の文章力が稚拙なので、キチンと良さを伝えられないのがとても悔しいです。。。

それに自分の認識が間違っているものも多々あると思います。。。

ただいいたいのは、すげー感動したということです。

冗談ではなく、涙がでそうなほどでした。

これをいうと嘘っぽくきこえてしまうんですが、本当なのでどうしてもいいたかったです。

現状の環境を変えたいけど、うまく変えられない、伝えられないという憤りを感じている人に是非読んでほしいです。

きっと、何かをつかめる「きっかけ」もしくは、何かを始めようと思う「熱」をもらえる本だと思います。

おしまい。

React入門を読み始めた(パート3)

はじめに

こんばんは。続いてReact勉強してます。

前回はこちら

今回から、勉強するときのメンツが集まりやすくなったから、頻繁にできそうかも。

わくわく。

React入門 React・Reduxの導入からサーバサイドレンダリングによるUXの向上まで (NEXT ONE)

React入門 React・Reduxの導入からサーバサイドレンダリングによるUXの向上まで (NEXT ONE)

やってみた

目次

今回やったのはこちら

  1. ライフサイクル
  2. Reduxでアプリケーションの状態を管理しよう(途中まで)

ライフサイクル

ライフサイクルメソッドは前回で少し説明したとおり、ClassComponentに備わっている独自メソッド。

大きく分けて3種類で、その3種類の中でもさらに細かく分かれている。

  • マウントに関するライフサイクルメソッド

    • componentWillMount
    • componentDidMount
    • componentWillUnmount
  • データのアップデートに関するライフサイクルメソッド

    • componentWillReceiveProps
    • shouldComponentUpdate
    • componentWillUpdate
    • componentDidUpdate
  • エラーハンドリングに関するライフサイクルメソッド

    • componentDidCatch

1. マウントに関するライフサイクルメソッド

componentWillMount

コンポーネントがマウントされる直前に実行されるメソッド。

ちなみに「マウントされた状態」というのは、Reactコンポーネントのrender()が初めて呼ばれたときが、マウントされた状態ということのようだ。

つまりこの componentWillMount は render()が初めて呼ばれる直前に呼ばれるメソッドということ。

使いみちはどんな感じなんだろう。

constructor()が終わって、render()が走る前にやりたいことがあまり思い浮かばない。

componentDidMount

コンポーネントがマウントされた直後に実行されるメソッド。

マウントされたあと(render()が終わったあと)なので、実際のDOMにアクセスできるから、イベントリスナーを登録したりするのに、最適なタイミングみたい。

componentWillUnmount

コンポーネントがアンマウントされる直前に実行されるメソッド。

「アンマウントされた状態」というのは、DOM上から対象のコンポーネントがなくなったときに、アンマウントされた状態ということのようだ。

DOMがなくなったときに実行するので、destructor()的なイメージかと思う。

なので、もろもろの掃除をしてあげるのが良さそう。

2. データのアップデートに関するライフサイクルメソッド

componentWillReceiveProps

propsを受け取る直前に呼ばれるメソッド。

このメソッドの引数には、新たに受け取る予定のpropsがある。

componentWillReceiveProps(nextProps)
{
}

このメソッドの引数の nextPropsは新たに受け取るpropsが入っていて、this.propsには、以前に受け取ったprops(更新前のprops)が入っている。

なので、新たに受け取ったpropsと、受け取る前(更新前)のpropsを比べる処理などがかける...と思う...

shouldComponentUpdate

propsやstateに変更があったときに呼ばれるメソッド。

このメソッドの引数には、新たに受け取る予定のpropsとstateがある。

shouldComponentUpdate(nextProps, nextState)
{
}

このメソッドにはtrue or falseの戻り値があり、trueを返すと、render()を実行し、falseを返すとrender()が実行されなくなる。

前回と同じpropsやstateが送られた場合は、render()を実行する必要がないのでfalseを返して、無駄なrender()を走らせないようにすることができる...らしい。

componentWillUpdate

render()が呼ばれる前に呼ばれるメソッド。

このメソッドの引数には、新たに受け取る予定のpropsとstateがある。

componentWillUpdate(nextProps, nextState)
{
}

2回目以降 のrender()が呼ばれるたびに、その直前に実行される。

先に説明した、componentWillMount() は初めてrender()が実行される直前に呼ばれるので、このメソッドは使いみちが違うっぽい。

componentDidUpdate

render()が呼ばれた直後呼ばれるメソッド。

このメソッドの引数には、以前のpropsとstateがある。

componentDidUpdate(prevProps, prevState)
{
}

2回目以降 のrender()が呼ばれるたびに、その直後に実行される。

コレも同じく、先に説明した、componentDidMount()とはタイミングが違うので、使いみちが違う。

でも前の状態のpropsやstateを持って何をするんだろう??

例えば割引額を表示するコンポーネントだったとして、選んだ割引クーポンごとに、金額の差額を表示するとかかな??

うーん。

本の解説では、DOMへアクセスするタイミングとしてはここが一番とのこと。てことは↑の例も当たりってことかな?

3. エラーハンドリングに関するライフサイクルメソッド

componentDidCatch

コンポーネントでエラーが起こったときに呼ばれるメソッド。

引数には、スタックトレースのerrorと、その他情報が入ったinfoがある。

componentDidCatch(error, info)
{
}

あくまで子コンポーネントでエラーが起こった時に呼ばれるので、つまり、この componentDidCatch を記述したコンポーネントでエラーが発生しても呼ばれない。

Reduxでアプリケーションの状態を管理しよう

前々回くらいでやったReduxで、前回と同じようなTODOアプリケーションを作ろうというスタンス。

ボリュームが多かったので、途中までで止まってる。

今回やったのは、Storeを生成して、ユーザーの行動を思わせるような擬似的なActionを作成し、そのActionを、生成したStoreにわたし、StoreにセットされているReducerが、状態を変化させる

というところまでをやってみた。

コード

Action

Actionを生成するための関数(ActionCreator)を用意する。

const addTask (task) => ({
  type: 'ADD_TASK',
  payload: {
    task
  }
});

Actionの形式には、Flux Standard Action という標準化された形式があるみたい。

↑の形がそう。

なので、Actionの要素も決まっている。

  • payload

    Actionに伴うデータとして利用できる。

  • error

    エラーを表現したい場合にはtrueにしてあげる。それに伴ってpayloadの中身も変化させてあげる。

  • meta

    payloadとは別の情報を含めたい場合に利用できる。

Reducer

Storeにセットする用のReducerを作成する。

const initialStore = {
  tasks: []
};

function addReducer(state = initialStore, action) {
  switch (action.type) {
    case 'ADD_TASK':
      return (
         ...state,
         tasks: state.tasks.concat([action.payload.task]);
      );
    default:
      return state;
  }
}
Store

状態管理を行うStoreを作成する。

import { createStore } from 'redux';

const store = createStore(addReducer);

createStore()で作成したstoreには4つのメソッドが存在している。

  • dispatch

    アクションを発行する。

const store = createStore(addReducer);
store.dispatch(addTask("タスク追加"));
  • subscribe

    ストアの更新が行われた際のコールバックメソッドを設定できる。

function changed() {
  console.log("変更されたよ!");
}
const store = createStore(addReducer);
const unsubscribe = store.subscribe(changed());

subscribe()の引数で受け取った unsubscribe を実行すると、subscribe()で設定したコールバックは呼ばれなくなる。

  • getState

    現在のStateを取得する。

const store = createStore(addReducer);
console.log(store.getState());
  • replaceReducer

    Reducerを切り替える。

const store = createStore(addReducer);
store.replaceReducer(別のReducer);

createStoreによって作成されたStoreにはReducerは一つしかセットできない。

なので、このような切り替えるためのメソッドがあるみたい。

アプリケーションが大規模なほど、Reducerも分割したほうが使いやすいとおもうけど、毎回切り替えるのはダルそう。というかミス起きそう。

今回はそこまで行けなかったので説明できないけど、そんなときのために combineReducer という 複数のReducerを一つにまとめるメソッドがあるみたい。

上記で書いた3つ(action, reducer, store)を組み合わせると以下のようなコードになる。

import { createStore } from 'redux';

const addTask (task) => ({
  type: 'ADD_TASK',
  payload: {
    task
  }
});

const initialStore = {
  tasks: []
};

function addReducer(state = initialStore, action) {
  switch (action.type) {
    case 'ADD_TASK':
      return (
         ...state,
         tasks: state.tasks.concat([action.payload.task]);
      );
    default:
      return state;
  }
}

function changed() {
  console.log("変更されたよ!");
}
    
const store = createStore(addReducer);
store.subscribe(changed());
store.dispatch(addTask('タスク1'));
store.dispatch(addTask('タスク2'));
store.dispatch(addTask('タスク3'));
console.log(store.getState());

=>
変更されたよ!
変更されたよ!
変更されたよ!
[タスク1, タスク2, タスク3]

こんな感じ!!!

おわりに

今回も結構面白い内容でした。

第一章でやったReduxの説明と概念は正直あんまわかってなかったけど、進めながらやると少しだけわかったような気もします。

まだまだ触りだけど。。。w

サイトの一部分だけReact + Redux導入ってやってみたいなーと思う今日このごろでした。

お疲れ様でしたー。

React入門を読み始めた(パート2)

はじめに

こんばんは。

今日は前回の続きをいつもと同じく社内のデザイナーさん(@chups_coke)と、React入門の本を読み進めました。

だいぶ時間空いたのは、僕もデザイナーさんも体調崩していたからなのです・・・。

React入門 React・Reduxの導入からサーバサイドレンダリングによるUXの向上まで (NEXT ONE)

React入門 React・Reduxの導入からサーバサイドレンダリングによるUXの向上まで (NEXT ONE)

やってみた

目次

今回読み進めたのは以下。

  1. Reactコンポーネント
  2. stateとイベントハンドリング

Reactコンポーネント

Reactのコンポーネントの種類は大きく分けて2種類が存在しているとのこと。

  • Functional Component
  • Class Component

関数定義のコンポーネントとクラス定義のコンポーネントということ。

Functional ComponentとClass Componentの違い

違いは定義の違いだけではなく、ClassComponentには、コンポーネントの状態を記録管理する state という概念が存在している。

また、ClassComponentには、ライフサイクルメソッドという独自メソッドも存在しているらしい。

iosとかのviewDidLoadとかとおんなじ感じかな??

Reactエレメント

他の言語でいうインスタンスとのこと。

# これはReactコンポーネント
const Test = () => {
  return (
    <div>あああ</div>
  );
};

ReactDOM.render(
  <div>
    # これはReactエレメント
    <Test />
  </div>,
  document.getElementById('root')
);

Flagmentコンポーネント

Reactコンポーネントは単一の親からなる要素しか返せないとのこと。

以下の書き方は「単一の親ではない」のでNG

const Test = () => {
  return (
    <div>あああ</div>
    <div>いいい</div>
  );
};

以下の書き方は、「単一の親」なのでOK

const Test = () => {
  return (
    <div>
      <div>あああ</div>
      <div>いいい</div>
    </div>
  );
};

とりあえず上記で通るけど、これだと出力されるHTMLに本来いらないHTMLタグが追加されてしまう。

こういうときにFlagmentコンポーネントが使えるみたい。

const Test = () => {
  return (
    <React.Fragment>
      <div>あああ</div>
      <div>いいい</div>
    </React.Fragment>
  );
};

一番上でくくっている <React.Fragment> は出力時にはHTMLとして処理されないので、最終的に出力されるHTMLは、以下のようになる。

<div>あああ</div>
<div>いいい</div>

<React.Fragment><></> みたいな感じで省略記法を使うことが出来るみたいだけど、個人的に圧倒的に可読性落ちちゃうので、使わないと思う。。。

データの受け渡し(props)

要は引数を渡せるということ。

const Test = (props) => {
  return (
    <div>{props.name}</div>
  );
};

ReactDOM.render(
  <div>
    <Test name="あああ" />
  </div>,
  document.getElementById('root')
);

propsという名前は、なんでもいいけどpropsとつけるのが一般的とのこと。

object型なので、今回は nameを渡してるけど、 当然他にもいろいろと渡せる。

渡せる値は、文字列でも数字でも関数でもオブジェクトでも基本的に何でも渡せるっぽい。

例外あるのかな?

children

コンポーネントを組み合わせて(繋ぎ合わせて)使うReactでは、これが結構重要な感じがした。

propsの特別なプロパティとして、childrenは存在しているみたい。

Reactコンポーネントの小要素が入ってくる

const Test = (props) => {
  return (
    <div>テストだよ!{props.children}</div>
  );
};

ReactDOM.render(
  <div>
    <Test>
      テストテスト
    </Test>
  </div>,
  document.getElementById('root')
);

出力されるHTMLは以下

<div>
  <div>テストだよ!テストテスト</div>
</div>

こんな感じで文字列をchildrenに渡すことが出来るが、Reactエレメントを渡すことが出来る。

const Test1 = () => {
  return (
    <div>テストだよ!</div>
  );
};

const Test2 = (props) => {
  return (
    <div>
      <p>今日のテスト</p>
      {props.children}
    </div>
  );
};

ReactDOM.render(
  <Test2>
    <Test1 />
    <Test1 />
    <Test1 />
  </Test2>,
  document.getElementById('root')
);

出力されるHTMLは以下

<div>
  <p>今日のテスト</p>
  <div>テストだよ!</div>
  <div>テストだよ!</div>
  <div>テストだよ!</div>
</div>

多分一番の使い所は、この使い方なのかも。

propTypes

propsに渡す値の型をチェックできる機能のよう。

今回の勉強会では、一緒にやっているデザイナーさんと足並み揃えてやりたかったので、プログラムよりな部分はやらないように、こちらは飛ばした。

stateとイベントハンドリング

stateは最初に書いたとおり、コンポーネントの状態を記憶しておく機能のこと。

本では、簡単なtodoアプリを作りながらの説明だったので、本に沿って実際につくってみた。

f:id:kojirooooocks:20180530042511g:plain

重要なところは、フォームに文字を入力した際にstateを変更させるためのchangeイベントと、登録ボタンを押したときに、todoリストに追加するためのclickイベント。

handleChange(e) {
  this.setState({
    value: e.target.value
  });
}

handleClick() {
  this.props.addTodo(this.state.value);
}

render() {
  return (
    <div>
      <input placeholder="新規TODOを入力してください" onChange={this.handleChange} />
      <button onClick={this.handleClick} >登録</button>
    </div>
  );
}

this.stateはClass Componentの重要なプロパティで、このstateでReactは各コンポーネントの状態を管理しているらしい。

stateの値を変更する場合は、直接修正せずかならず setState() 経由で修正しなければいけない。

終わりに

今回やったtodoアプリはgithubにあげときます。

kojirock/react-sample01

今回はガッツリコンポーネントのことを勉強できたから、勉強した感がありました。

次はライフサイクルのことを勉強するようなので、間を空けずにやっていきたいです。

おやすみなさい。

コマンドからのcloudfrontのオブジェクト削除

はじめに

こんばんは。

めっちゃ簡単というか、小ネタです。

なので、下書きもありません。

やってみた

実際のコマンド

$ aws cloudfront create-invalidation --distribution-id $DISTRIBUTION_ID --paths 'パス'

今入っている現場では、jenkins経由で beanstalkにdeployを行ってます。

deploy対象のディレクトリがgitレポジトリという状況になっているので、例えばjsのオブジェクトを削除したいならば

MODIFY_JS_FILE_COUNT=`git log --name-status -n 1 --oneline | tail -n +1 | grep .js | awk '{print $1}' | grep 'M' | wc -l`
if [ $MODIFY_JS_FILE_COUNT -ne 0 ]; then
  aws cloudfront create-invalidation --distribution-id $DISTRIBUTION_ID --paths '$JS_PATH' --profile=$DEPLOY_USER
fi

みたいな感じで、編集があった場合のみ、まるっと消してます。 作り込んだら各ファイルごとに消すことも可能ですが、規模的に全体の削除にしています。

終わりに

こんな泥臭い方法しか思い浮かばなかったので、ほかにもっとスマートにやれる方法があればぜひ教えてください。。。

まじですぐ終わった。

React入門を読み始めた

はじめに

こんばんは。

今日はお世話になっている会社で

React入門 React・Reduxの導入からサーバサイドレンダリングによるUXの向上まで

という本を、社内のデザイナーさんと読み始めたので、記録として残しておきます。

React入門 React・Reduxの導入からサーバサイドレンダリングによるUXの向上まで (NEXT ONE)

React入門 React・Reduxの導入からサーバサイドレンダリングによるUXの向上まで (NEXT ONE)

ReactNativeでアプリを使うための前段として、Reactをしっかりやってみたなと思い、企画しました。

今日は3時間程度しかやれてないので、ぶっちゃけReact本格的に触るところまで行ってません。

やってみた

目次

今回読み進むことが出来たのは以下。

  1. React・Reduxとは

  2. create-react-appで開発を始めよう

  3. JSX

React・Reduxとは

React

見た目(HTML)と機能(JS)を一塊にした コンポーネント をReactでは容易に作成することが出来る。

この コンポーネント を増やしたり組み合わせたりしながらページを作っていく。

この辺はなんか、Vueもおんなじようなこといってたな。

Reactの特徴としては以下

・VirtualDOM

・JSX

VirtualDOM(仮想DOM)

React内で仮想のDOMを管理している感じ。

JqueryとかでガリガリDOM操作を行うと、毎回レンダーツリーの更新がされるらしく、その後始まるレイアウト・ペイント処理がさらに行われる。これがブラウザによってパフォーマンス低下の原因にあるとのこと。

仮想DOMは、実際のDOMのレンダリングフローとは切り離されているところにあるので、仮想DOMで諸々変化を行って、その変化の差分を算出して、その差分だけ実際DOMを変化させるとのこと。 (この辺イメージつかめてません)

多分、過程ではなく結果だけを実際のDOMに伝えるから最小限の変化だけでいいという意味なのかな・・・?

JSX

Javascriptを拡張した言語。

XMLライクに書けていけるってのが強みのようです。

だいぶ前にサンプルでやった、ReactNativeでも使われてて、うーんと慣れなかった記憶がある。

classがclassNameだったり、forがhtmlForだったりと、そもそもJSコードの中にバリバリHTML的な記述を書いてくことに対して、うん?と思ってしまう。

だけど、Reactを書くにあたって、JSXを覚えたほうが記述しやすいので覚えたほうがいい。

サンプルコードもJSXで書かれてるしね。大体。

Flux

この辺説明できるほど、理解できてないのが正直なところ。。。

ただ、ReactやるならFlux適用しようね!ってはなしではなく、Fluxはこういう作り方が出来るよっっていうデザインパターンという位置づけだということ。

一応、流れを本から引用すると

ユーザーの入力からActionを作成し、そのActionをdispatchすることでStoreにデータを保存し、Viewに反映させるいった、流れを取ります。データが一方向のフローで流れるため、複雑なアプリケーションになっても不整合が置きづらい仕組みになっています。

なるほどわからん

以前の記事でまとめてるけど、振り返ってもわからん

とりあえず読み進める。

Fluxは以下の4人の登場人物が存在する。

  • Action

    Viewで起きたイベントや、ajax通信のリクエストなど「アプリケーションの状態の変化内容」をDispatcherを伝える役割 かな?

  • Dispatcher

    ActionをStoreに受け渡す役割(MVCのコントローラ的な?)

  • Store

    Dispatcherから渡されたActionを元に、アプリケーションの状態を更新させる

    ビジネスロジック各場所ともいえるのかな?

  • View

    Storeの更新にともなって、表示側を更新する?

Redux

Fluxの派生デザインパターンという立ち位置

名前的にReactと使うのがマストなんでしょ?って感じだけど違うみたい。

そもそもFlux自体使わなくてもいいって話だから、これもそういうこと。

じゃあなんでそんな紛らわしい名前つけたんだろう・・・

後読み方はどう読むの?れでゅっくす?

Redux3原則

Reduxの思想として大事な3つのお約束があるみたい。

  • Single source of truth
  • State in read-only
  • Changes are made with pure functions

正直あんまわかんなかった。

Reduxには、Fluxの登場人物のほかにもう一人の登場人物が存在する。

Reducer

状態を変化させるための関数

DispatcherにActionが渡される前に動くのかな?

それとも「状態を変化させるため」の関数だから、Storeに渡される前なのかな?

この辺は謎。読み進めて、コード書いてけば少しは分かるかな。。。?

create-react-appで開発を始めよう

node.jsのインストールとか、最初のHello Worldなのでココはサラッと読み飛ばす

JSX

JSXでの記述方法などの説明。

メソッド埋め込めるよ!とか、変数埋め込めるよ!とか基本的なところ、ココもそこまで迷わなそう。

すこしだけ戸惑ったのは、モジュールバンドラーのwebpackの実行。

webpackとbabelのインストールと実行自体は、少し前に触ったのである程度は分かるけど、webpackの実行でwarningが出た

 ./node_modules/.bin/webpack --config webpack.config.js 

WARNING in configuration
The 'mode' option has not been set, webpack will fallback to 'production' for this value. Set 'mode' option to 'development' or 'production' to enable defaults for each environment.
You can also set it to 'none' to disable any default behavior. Learn more: https://webpack.js.org/concepts/mode/
f

本では特に書かれてなかったんですが、この本で紹介されているwebpackのバージョンは 3.10.0 で今落としてきたバージョンは

$ ./node_modules/.bin/webpack --version
4.8.3

という感じでメジャーバージョンがあがってるようで、このエラーが出てるみたい。

英語はちんぷんかんぷんだけど、なんとなく

「modeをdevelopmentかproductionで指定して実行しろYO」

って言ってる模様。

実行してみる。

$ ./node_modules/.bin/webpack --config webpack.config.js --mode production
Hash: 2328f0123ddc3abb5e49
Version: webpack 4.8.3
Time: 2856ms
Built at: 2018/05/18 4:04:53
    Asset     Size  Chunks             Chunk Names
output.js  106 KiB       0  [emitted]  main
Entrypoint main = output.js
[6] ./entry.js + 1 modules 323 bytes {0} [built]
    | ./entry.js 174 bytes [built]
    | ./Hello.js 139 bytes [built]
    + 14 hidden modules

WARNING消えた!よかったー。

終わりに

前回はVueのチュートリアル触って、今回はReactといろいろ触ってるのですが、何がしっくり来るかもわかってないし、そもそも取捨選択できるほど、それぞれをしっかりと知っているわけではないので、とりあえずのフェーズとして触りまくるというのはいいかもしれないなと思ってます。

自分の進め方としては、

一緒に勉強するのはReact

一人で勉強するのはVue

という感じで考えてます。

React終わったらAngularもやりたいな。とりあえず読み進めてみます。おやすみ。

cakephp3でajax(post)通信

こんばんは。小ネタというか、今さっき覚えたことです。

js側

var save_data = {
   ....
   ...
   ..
   .
};

$.post({
    url:      '/test/ajaxSave',
    dataType: 'json',
    data:     save_data
}).done(function(response) {
    if (response.result === 'NG') {
        alert('保存失敗');
        return false;
    }
    
    alert('保存成功');
    return true;
}).fail(function() {
    alert('通信失敗');
});

php(Controller)側

<?php

class TestController extends AppController
{
    public function ajaxSave()
   {
        if (!$this->getRequest()->isAll(['ajax', 'post'])) {
            return $this->getResponse()->withType('json')->withStringBody(json_encode([
                'result' => 'NG'
            ]));
        }

        // 何かの保存処理

        return $this->getResponse()->withType('json')->withStringBody(json_encode([
            'result' => 'OK',
        ]));
    }
}

これで通信可能。

ajax通信かつ、postの通信かどうかをisでどう判断するのかとコアを見てたら、isの第一引数は配列OKだったけど、

<?php

        if (is_array($type)) {
            $result = array_map([$this, 'is'], $type);

            return count(array_filter($result)) > 0;
        }

という感じでどれか一つだけでもtrueであればOKになっちゃうので使えなかった。

他を探すと isAll() というドンピシャのやつがあったので、これを使用しました。

<?php

    public function isAll(array $types)
    {
        $result = array_filter(array_map([$this, 'is'], $types));

        return count($result) === count($types);
    }

is() の第一引数配列で渡されたら、 isAll() を走らせればいいのに・・・

小さなチーム、大きな仕事を読んで

はじめに

こんばんは。

食中毒で気持ち悪いのが続いていて、体調が悪い僕です。

久しぶりに本読みました。

小さなチーム、大きな仕事という本です。

小さなチーム、大きな仕事〔完全版〕: 37シグナルズ成功の法則

小さなチーム、大きな仕事〔完全版〕: 37シグナルズ成功の法則

  • 作者: ジェイソン・フリード,デイヴィッド・ハイネマイヤー・ハンソン,黒沢 健二,松永 肇一,美谷 広海,祐佳 ヤング
  • 出版社/メーカー: 早川書房
  • 発売日: 2012/01/11
  • メディア: 単行本
  • 購入: 21人 クリック: 325回
  • この商品を含むブログ (39件) を見る

経営者目線でのビジネス本という感じでしたが、エンジニア目線でも、

なるほど。

と思うところもあったので、また個人的に刺さった文章を記録しておこうと思います。

記録

1. 現実の世界なんて無視しよう

あなたが希望と野心にあふれていれば、そのアイディアは不可能だと説得しようとするだろう。時間の無駄だと。 信じてはいけない。そういう世界は彼らに取ってはリアルかもしれないが、あなたがそこに生きる必要はない。

何も試さないことを正当化しようとするものだ。あなたには関係ない。

新しいサービスのアイディアを閃いた時、他人からこれを言われることもあるし、自分自身がこれを言ってくる可能性もある。

でもそれはそれ。試さずに終わるのが一番もったいない。

2. 「失敗から学ぶこと」は過大評価されている

統計に騙されるな。他人の失敗は、しょせん他人の失敗だ。

失敗から何を学べるのだろうか。してはいけないことについては学べるかもしれないが、それにどんな価値がある?次に何をすべきかがわからないではないか。

成功から学ぶことと比較しよう。成功は次の手段を与えてくれる。成功すれば、何がうまくいったのかわかり、それをもう一度できる。そして次はもっとうまくやれるだろう。

失敗から学ぼうっていう言葉はよく聞くけど、この考えは面白かった。

ここまでバッサリ切り捨てなくてもいいとは思うけど、たしかに成功から学ぶほうがより良いことを吸収できるかもしれない。

3. 仕事依存症(ワーカホリック)はバカげている

仕事依存症(ワーカホリック)は不必要なだけではなく、バカげている。たくさん働くことは、よりよいケアができることや、たくさん達成できることを意味しない。単にたくさん働いたというだけだ。

仕事依存症患者は重要な点を見逃している。彼らは時間をつぎ込んで、なんとかしようとする。よく考えることをせず、力技で埋め合わせしようとする。これは見苦しい解決につながるだけだ。

まぁこんな会社は流石に最近はないと思うけど、頑張って残業して仕事してますよ感を出す人はいまだにいたりする。

残業してない人はこの人達に毎回気を使っていたりするので、こういう人たちは、存在だけで空気を悪くしているということを理解してほしい。

4. 「時間がない」は言い訳にならない

一番多い言い訳は「時間がない」だ。

そんなわけはない。正しく使えば時間はあるものだ。

普段の仕事をしながら、夜中にプロジェクトをスタートさせればいい。

テレビを見たり、オンラインゲームをする代わりに、アイディアをまとめよう。10時に寝るかわりに11時に寝よう。

自分もそうだけど、よく言っちゃう。他の本でも書いてたけど、とにかく毎日時間を作ることが大事。

そして続けることが大事。

あと、この一文も気に入った。

何かを始めるには、これで十分だ。始めてみれば、興奮と興味が本物なのか、それとも言ってみただけなのかがわかる。うまくいかなかったら、今までと同じように毎日働けばいい。ちょっとした時間以外は、何も失わないので、大げさな話にはならない。

やるぞ!とその気になっても、「ちょっと違ったな」と思えば、やめればいい。

やるのもやらないのも自由だけど、やったところでリスクはないってことだ。

5. 決断することで前に進む

できるだけ「これについて考えよう」ではなく「これについて決断を下そう」と思うことだ。決断する姿勢を持つことだ。完璧な解決を待たず、決断して前進するのだ。

決断に決断を重ねる流れに入ると、勢いが生まれ、モチベーションも高まる。決断は進捗だ。あなたが決めた一つ一つのものは、あなたの土台の一分となる。「あとで決める」を積み重ねていくことはできないが、「決断したこと」を積み重ねていくことはできるのだ。

こういうのことって、MTGでよくやってしまいがち。

「○○のことについて話す」というお題でMTGやったりするけど、そもそもその始まりが間違ってるということ。

「○○のことについて、解決策を1つ以上決める」みたいな感じでキチンとゴールを決めて始めるべき。

6. 長過ぎるToDoリストは終わることがない

長いリストは罪悪感を抱かせる。完了していない項目のリストが長くなればなるほど、あなたの感情はネガティブなものになるだろう。

長いリストを、いくつものより小さなリストに分解するのだ。たとえば100項目の1つのリストを10項目の10のリストへと分解する。これはリストの中の一つの項目を追えた時にリストの1%ではなく、10%を完了したことを意味する。

確かにあなたはまだ同じ量だけやることが残っている。でもあなたは小さな世界を見て、満足やモチベーション、そして進捗を得ることができる。これは巨大な世界を見つめて、ゾッとし、モチベーションを挫かれるよりもはるかにいい。

github issueとか見てると未着手のissueが150個とか溜まってて、ウッとなる。。。

zenhubとかでissueをまとめてepic単位で見れば精神的にも落ち着く。

まさにおっしゃる通り。

あと、この一文にもハッとした。

そして優先順位付けについてアドバイス。数字やラベルで優先順位を付けてはいけない。

そのようにすると、必ずといっていいほど、優先順位が高いタスクが山ほど生まれるハメになる。これは優先順位付けではない。

今まさにそうなってる(笑)

どれもこれも優先度S or A

一体どれが優先度高いのっていう状態。

結構アンチパターン当てはまってるなぁ

7. 小さな決断をする

大きな決断をするのは難しいし、変えるのも難しい。そして一度大きな決断をすると、たとえそうではなかったとしても自分は正しい決断をしたと信じ続ける傾向がある。客観的ではなくなってしまうのだ。

一時的に効率が上がる小さな選択をしよう。小さな決断であれば大きな間違いをすることはない。小さな決断なら、変更の余地がある。失敗しても大きなペナルティはない。ただそれを修正するだけだ。

なるべく小さい粒度で作業しようってことかな。

コミットもロールバックもテストも簡単だし、レビューしてもらうのも簡単。

うん。そういう意味でとっておこう。

8. 熱意と優先順位を混同するな

新しいアイディアへの熱意は、そのアイディアが持つ本当の価値の正確な指標ではない。たった今、確かなひらめきが生まれたように見えたものも、次の朝にはただの「あってもいい考え」に格下げとなっていることがある。そして「あってもいい考え」には、他のすべてのことを延期するほどの価値はない。

すげーささる。

新しいもの好きの自分としては、興味あることを優先的に勉強したい試したいと思ってしまう。

しかしその優先順位は完全に自分の熱意分が上乗せされている。

これは、よくないな。

要改善だ。

終わりに

経営者向けの話が多かったですが、自分にも当てはまるようなことが多かったです。

特に最後なんか、読んでて笑ってしまいました。

久しぶりに本読んだので、時間もかかったし疲れましたが、またコンスタントに本読めていければと思います。

積み本も多いので。。。

ではでは。